CF 550C 數學 or dp

鏈接:http://codeforces.com/problemset/problem/550/C

題意:給你一個長度最大爲100的整數,問你能不能去掉這個整數裏面的數字,使去掉後的整數能被8整除。


思路:

題解的數學方法:一個數要是能被8整除,只要後面三位能被8整除就可以了。因爲一個數總可以寫成num =...... 1000 * x + 100 * y + 10 * z + t的形式,1000能被8整除,所以大於等於1000以上的就不用考慮,只要考慮後三位即可,那麼直接暴力從原整數中取出1,2,3長度的數,只要有能被8整除的就是答案。

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
typedef long long ll;
const int maxn = 75;
const int INF = 0x3f3f3f3f;

string s;
vector<string> vec[4];
int main()
{
	while(cin>>s)
	{
		for(int i = 0;i < 4;i++)vec[i].clear();
		int len = s.length();
		for(int i = 0;i < len;i++)
		{
			string s1 = "";
			s1 += s[i];
			vec[1].push_back(s1);
			for(int j = i + 1;j < len;j++)
			{
				string s2 = s1;
				s2 += s[j];
				vec[2].push_back(s2);
				for(int k = j + 1;k < len;k++)
				{
					string s3 = s2;
					s3 += s[k];
					vec[3].push_back(s3);
				}
			}
		}
		int ans = -1;
		int num;
		for(int i = 1;i <= 3;i++)
		{
			for(int j = 0;j < vec[i].size();j++)
			{
				if(i == 1){
					num = vec[i][j][0] - '0';
				}else if(i == 2){
					num = (vec[i][j][0] - '0') * 10 + (vec[i][j][1] - '0');
				}else if(i == 3){
					num = (vec[i][j][0] - '0') * 100 + (vec[i][j][1] - '0') * 10 + (vec[i][j][2] - '0');
				}
//				cout<<num<<endl;
				if(num % 8 == 0)
				{
					ans = num;
					break;
				}
			}
			if(ans != -1)break;
		}
		if(ans == -1)
		{
			printf("NO\n");
		}
		else 
		{
			printf("YES\n%d\n",ans);
		}
	}
}



自己的dp方法(題解裏也有說,不知道一不一樣):

設狀態轉移方程爲dp[i][j],表示取到第i位數時餘數爲j的情況是否存在,存在則dp[i][j] = 1。然後從前向後枚舉,如果j=0這種情況出現則說明有符合答案,那麼根據輔助數組mark往前找答案,將答案還原

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
typedef long long ll;
const int maxn = 102;
const int INF = 0x3f3f3f3f;

string s;
int dp[maxn][8];
int mark[maxn][8][2];

int main()
{
	while(cin>>s)
	{
		int len = s.length();
		mem(dp,0);
		mem(mark,0);
		int qian = -1,hou = -1;
		for(int i = 0;i < len;i++)
		{
			int val = (s[i] - '0') % 8;
			dp[i][val] = 1;
			mark[i][val][0] = -1;
			mark[i][val][1] = -1;
			if(s[i] == '8' || s[i] == '0')
			{
				qian = s[i];
				break;
			}
		}
		if(qian != -1)
		{
			puts("YES");
			printf("%c\n",(char)qian);continue;
		}
		for(int i = 1;i < len;i++)
		{
			int now = s[i] - '0';
			for(int j = 0;j < i;j++)
			{
				for(int k = 0;k < 8;k++)
				if(dp[j][k] ==  1)
				{
					int cur = k * 10 + now;
					cur %= 8;
					if(cur == 0)
					{
						qian = i,hou = cur;
					}
					mark[i][cur][0] = j;
					mark[i][cur][1] = k;
					dp[i][cur] = 1;
				}
				if(qian != -1)break;
			}
			if(qian != -1)break;
		}
		if(qian == -1)
		{
			puts("NO");continue;
		}
		string ans = "";
		while(1)
		{
			ans += s[qian];
			int tempqian = qian,temphou = hou;
			qian = mark[tempqian][temphou][0];
			hou = mark[tempqian][temphou][1];
			if(qian == -1)break;
		}
		reverse(ans.begin(),ans.end());
		puts("YES");
		for(int i = 0;i < ans.length();i++)
		{
			printf("%c",ans[i]);
		}
		printf("\n");
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章