FZU Problem 1895 整除45问题(整除问题+字符串维护+优化)

时间:2021-04-03 16:30:15

这个题有点烧脑啊,但是只要想清楚被45整除的数,肯定能被5和9整除,能被9整除的数各位加起来肯定是9的倍数,能被5整除的末尾是0或5.

然后dfs的过程稍微不太好懂,还有几个优化必须要注意.dfs的过程是选出哪些数我们不要,而且不要的数越少越好,所以删除的数在dfs的过程中应该越来越小,这一步必须有,否则超时.

输出的时候也需要注意下0的情况,只能输出一个0,下面是代码

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = ;
const int M = ;
const int dir[]= {,};
int tmp, rec[M], cnt[M];
int n, s[N], x, id;
bool flag;
char ans[N];
bool cmp(char *a, char *b)
{
for(int i=; a[i]; i++)
{
if(a[i]!=b[i]) return a[i] < b[i];
}
return false;
}
void dfs(int m, int d, int sum)
{
if(d>=m)
{
if((sum-tmp)% == )
{
char now[N];
memset(now,,sizeof(now));
int len = ;
for(int i=; i>=; i--)
{
for(int j = ; j < cnt[i]; j++)
now[len++] = i + '';
}
now[len++] = dir[id] + '';
if(m < x || (cmp(ans, now) && m == x))
{
flag = true;
x = m;
strcpy(ans, now);
}
}
return;
}
for(int i = ; i <= ; i++)
{
if(!cnt[i]) continue;
cnt[i]--;
dfs(m, d+, sum+i);
cnt[i]++;
}
}
int main()
{
int cas;
scanf("%d", &cas);
for(int i=; i<=cas; i++)
{
char num[N];
scanf("%s", num);
x = strlen(num), tmp = ;
flag = false;
memset(rec, , sizeof(rec));
memset(ans, , sizeof(ans));
for(int i=; i<x; i++)
{
int cur = num[i] - '';
tmp += cur;
rec[cur]++;
}
for(int i=; i<; i++)
{
memcpy(cnt, rec, sizeof(rec));
cnt[dir[i]]--;
if (cnt[dir[i]] < ) continue;
id = i;
for(int j=; j<=tmp && j<=x; j++)
dfs(j, , );
}
if(!flag)
{
printf("impossible\n");
continue;
}
int lenss = strlen(ans),sum1 = ;
for(int i = ; i < lenss; i++)
{
sum1 += ans[i] - '';
}
if(sum1 == )
{
puts("");
continue;
}
puts(ans);
}
return ;
}