鏈接:點擊打開鏈接
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
*/