1. 程式人生 > 其它 >記錄一些面試題

記錄一些面試題

攜程2022.04.14

題目大意:一個數字串。從中選取一個子序列使其實9的倍數,有多少種方案,允許有前導0,對1000000007取模
輸入
1188
輸出
5
輸入
0123
輸出
1

位數值之和是9的倍數則序列是9的倍數,遍歷數串,當前值可取可不取,若取則會對前面的值產生影響,若當前數值為x,則依次加0~9之後會對應更新,不取的話就是本身,則新的值就是dp[i][j + x] = dp[i - 1][j] + dp[i - 1][j + x],用滾動陣列維護就行。

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define ll long long int
int main(){
	string s;
	cin >> s;
	ll vis[2][10], flag = 0; // 維護9個數字的個數
	memset(vis, 0, sizeof(vis));
	for(int i = 0, x; i < s.size(); i++){
		x = s[i] - '0';
		x %= 9;
		for(int j = 0; j < 9; j++){
			int k = (j + x) % 9;
			vis[flag][k] = (vis[flag ^ 1][j] + vis[flag ^ 1][k]) % mod; // 當前數字取 or 不取
		}
		vis[flag][x] = (vis[flag][x] + 1) % mod; //單獨作為一個序列
		// for(int j = 0; j < 9; j++)
		// 	cout << vis[flag][j] << " ";
		// cout << endl;
		flag ^= 1; // 更新狀態,用兩個陣列交替維護
	}
	cout << vis[flag ^ 1][0] << endl; // 最後所有數字取完之後,0對應的數字就是方案的數目
	return 0;
}