链接:点击打开链接
A:水题,不解释
#include<iostream>
#include<cstdio>
using namespace std;
__int64 a[160][22]={0,1},tem,n;
int main()
{
int i,j,t;
scanf("%d",&n);
for(i=1;i<=n;i++)a[1][i]=1;
for(i=2;i<=n;i++)
{
for(j=1;j<=n;j++)
a[i][j]=a[i-1][j]+a[i][j-1];
}
printf("%I64d\n",a[n][n]);
return 0;
}
B:就是有n堆石头,给你k种颜色去给每堆石头涂色,且任意两堆石头同种颜色个数差应<=1,比如第一堆涂红色的有1个,那么其它堆的涂红色石头应在[0,2]范围
我的策略就是从循环从1~k涂色,最后不足k则 1~rr (rr=b[i]%k)涂色;
#include<iostream>
#include<cstdio>
using namespace std;
int a[160],tem,n;
int main()
{
int i,j,t,k,rmax,rmin;
scanf("%d%d",&n,&k);
int tmax=0,tmin=111;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
tmin=min(tmin,a[i]);
tmax=max(tmax,a[i]);
}
int flag=0,ti;
if((tmax/k-tmin/k)<1)flag=1;
else if((tmax/k-tmin/k)==1)
{
rmax=tmax%k;
rmin=tmin%k;
if(rmax<=rmin)flag=1;
}
if(!flag)printf("NO\n");
else
{
printf("YES\n");
for(i=1;i<=n;i++)
{
t=a[i]/k; //循环t次从1~k涂色,最后不足k则 1~rr (rr=b[i]%k)涂色;
int rr=a[i]%k;
for(ti=1;ti<t;ti++)
{
for(j=1;j<=k;j++)printf("%d ",j);
}
if(rr)
{
if(t)for(j=1;j<=k;j++)printf("%d ",j);
for(j=1;j<rr;j++)printf("%d ",j);
printf("%d\n",j);
}
else
{
if(t)for(j=1;j<k;j++)printf("%d ",j);
printf("%d\n",j); //t和rr不同时为0
}
}
}
return 0;
}
C:
就是输入N个数b[i](1<=i<=n),每个b[i]是a[i](1<=i<=n)各个位数的数字和。
现在让你求最小的a[i]可能值
AC的在下边。
Wrong:(这个策略没按最小的还原a[i],原因是题目中If there are multiple sequences with least possible number an, print any of them.误解了,其实它只要求an最小,即最后一个还原出来的an最小即可)故若题目改一下这个版本也是正解--
#include <iostream>
#include<string>
#include<cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define mm 311
int b[mm],a[mm];
__int64 ans[mm];
string s[311];
int main()
{
int i=1,j,n,k,tmax=0,flag=1;
scanf("%d",&n);
scanf("%d",&b[i]);
flag=max(flag,b[i]/9+(b[i]%9!=0));
int last=b[i]/9+(b[i]%9!=0);
for(i=2;i<=n;i++)
{
scanf("%d",&b[i]);
if(b[i]<=b[i-1] )//&& last+1>flag)
{
last++;
if(last>flag)flag=last;
}
flag=max(flag,b[i]/9+(b[i]%9!=0));
last=max(last,flag);
}
i=n;
//cout<<"flag="<<flag<<endl; //
int tem=b[i];
for(j=flag;j>0;j--)
{
if(tem>=9)
{
//printf("9");
s[i]+='9';
tem-=9;
}
else if(tem==0)
{
//printf("0");
s[i]+='0';
}
else
{
//printf("%d",tem%9);
s[i]+=char(tem%9+'0');
tem=0;
}
}
//printf("\n");
for(i=n-1;i>=1;i--)
{
if(b[i]>=b[i+1])flag--; //==也要
int tem=b[i];
for(j=flag;j>0;j--)
{
if(tem>=9)
{
//printf("9");
s[i]+='9';
tem-=9;
}
else if(tem==0)
{
//printf("0");
s[i]+='0';
}
else
{
//printf("%d",tem%9);
s[i]+=char(tem%9+'0');
tem=0;
}
}
//printf("\n");
}
for(i=1;i<=n;i++)cout<<s[i]<<endl;
return 0;
}
AC:
#include <iostream>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int N;
string f(string p,int tot)
{
int i,sum=0;
for( i=0;i<p.size();i++) sum+=p[i]-'0';
bool done=0;
for( i=0;i<p.size();i++)//从个位开始向高位扫
{
sum-=p[i]-'0';<span style="white-space:pre"> </span>//跳过的次数=该位到个位的位数清0的个数
//cout << i << ' ' << p[i] << ' ' << sum <<" "<<tot<< endl;
if(p[i]=='9'||(sum+p[i]-'0')>=tot||sum+9+9*i<tot) continue;
//p[i]='9'就不能再通过该位+1来完成,sum+p[i]-'0'>=tot即需要更高位增加
//sum+9*(i+1)<tot:即判断是否在该位(包括该位)至个位全部置为9也比tot小则需要向高位增加
p[i]++;
tot-=sum+p[i]-'0';
for(int j=0;j<i;j++)
{
if(tot>=9)p[j]='9';
else p[j]=tot+'0';
tot-=p[j]-'0';
}
if(tot) p[i]+=tot;
done=1; //只要有一位增加就可以
break;
}
if(done) return p;
else return f(p+'0',tot);//增加一位数
}
int main()
{
cin >> N;
string t("0");
for(int i=0,b;i<N;i++)
{
cin >> b;
t=f(t,b);
//cout << string(t.rbegin(),t.rend()) << endl; //就是倒序输出
for(int j=t.size()-1;j>=0;j--)cout<<t[j]; cout<<endl;
}
return 0;
}
/*
10
8 8 5 1 2 7 3 8 9 4
*/