A题,至少能找到个 g c d = 2 gcd=2 gcd=2的,只要 2 2 2个都是偶数就行
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t;
ll n;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%lld",&n);
while(1)
{
ll x=n,res=0;
while(x)
{
res+=x%10;
x/=10;
}
if(__gcd(res,n)>1)
{
printf("%lld\n",n);
break;
}
else n++;
}
}
return 0;
}
B题 贪心,把 a [ i ] a[i] a[i]转化为 x x x ( 2 x = a [ i ] ) (2^x=a[i]) (2x=a[i]),用 c n t cnt cnt存下,每层从最大的开始遍历
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int t,n,w,x,cnt[110];
int main()
{
scanf("%d",&t);
while(t--)
{
memset(cnt,0,sizeof cnt);
scanf("%d%d",&n,&w);
for(int i=0;i<n;i++)
{
scanf("%d",&x);
int y=log2(x);
cnt[y]++;
}
int res=0;
while(n)
{
res++;
int x=w;
for(int i=65;i>=0;i--)
{
while(cnt[i]&&x>=pow(2,i))
{
x-=pow(2,i);
cnt[i]--;
n--;
}
}
}
cout<<res<<'\n';
}
return 0;
}
C题 动态规划, d p [ i ] [ j ] dp[i][j] dp[i][j]表示当前寿命为 j j j还需要穿过 i i i层的粒子最终会变成多少粒子,
由题意得 d p [ i ] [ j ] = d p [ n − i ] [ j − 1 ] + d p [ i − 1 ] [ j ] dp[i][j]=dp[n-i][j-1]+dp[i-1][j] dp[i][j]=dp[n−i][j−1]+dp[i−1][j]其中 d p [ n − i ] [ j − 1 ] dp[n-i][j-1] dp[n−i][j−1]表示产生了一个反向的粒子,寿命减一 ,还需要穿过 n − i n-i n−i层, d p [ i − 1 ] [ j ] dp[i-1][j] dp[i−1][j]表示原来的粒子,层数减一。初始化 d p [ 0 ] [ j ] = 1 ( 1 < = j < = k ) dp[0][j]=1(1<=j<=k) dp[0][j]=1(1<=j<=k),因为需要穿过0层的粒子最后就是自己。
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10,mod=1e9+7;
int t,n,k,dp[N][N];
int main()
{
cin>>t;
while(t--)
{
cin>>n>>k;
for(int i=1;i<=k;i++)dp[0][i]=1;
for(int j=1;j<=k;j++)
for(int i=1;i<=n;i++)
dp[i][j]=(dp[n-i][j-1]+dp[i-1][j])%mod;
cout<<dp[n][k]<<endl;
}
return 0;
}