Codeforces Round #289 (Div. 2, ACM ICPC Rules)

鏈接:點擊打開鏈接

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
*/




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