Codeforces Round #231 div2前三題

果7發表於2014-02-21

A題

題目地址:http://codeforces.com/contest/394/problem/A

題目大意:A+B=C,可能正確,可能不正確,然後你可以選擇移動1,比如A--,C++或者A++,C--或者不移動也可以。

如果可以便輸出可以的解決方案,不可以輸出Impossible

經過分析可以得到A+B==C或者A+B==C-2或者A+B==C+2,這樣可以通過移動或者不移動平衡,天平的原理。不過移動的時候注意不要讓A,B, C變成了0

AC程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;

char str[1005];

int main()
{
    int a,b,c;

    int i,j;
    while(cin>>str)
    {
        int len=strlen(str);
        a=b=c=0;
        for(i=0; i<len; i++)
        {
            if(str[i]=='|')
                a++;
            else
                break;
        }

        for(j=i+1; j<len; j++)
        {
            if(str[j]=='|')
                b++;
            else
                break;
        }
        for(i=j+1; i<len; i++)
        {
            if(str[i]=='|')
                c++;
        }

        //cout<<a<<" "<<b<<" "<<c<<endl;

        int flag=0;
        if(a+b==c)
        {
            cout<<str<<endl;
            continue;
        }
        if(a+b==c+2)
        {
            flag=1;
            if(a>b)
            {
                a--;
                c++;
            }
            else
            {
                b--;
                c++;
            }
        }
        else if(a+b==c-2)
        {
            flag=1;
            a++;
            c--;
        }

        if(flag)
        {
            for(i=0; i<a; i++)
                printf("|");
            cout<<"+";
            for(i=0; i<b; i++)
                printf("|");
            cout<<"=";
            for(i=0; i<c; i++)
                printf("|");
        }

        else
            puts("Impossible");
    }
    return 0;
}


B題,是個模擬題,但是自己卻誤認為是大數的問題,竟然想到了JAVA,完事兒之後覺得不太可能。

題目地址:http://codeforces.com/contest/394/problem/B

題目的意思是說,讓你找一個p位數,比如是XpXp-1...X1,再給你一個t,使得X1XpXp-1...X2=t*(XpXp-1...X1),如果找的到,選擇最小的XpXp-1...X1。開始自己硬推的公式,把前面的設為y,然後開始的數變為y*10+x,轉換之後的值變為x*10^p-1+y,然後方程變成了(y*10+x)*t=x*10^p-1+y,通過移動可以變為

(10^p-1-t)*x=(10t-1)*y,然後自己採取的方法是列舉x從1到9,然後求y,看y位數,還有整除..後來搞進去了,就一直在搞大數,後來覺得不太可能,10^1000000這個數為免太大了,最後還是TLE了,這是第一次打Cf用java程式碼。。

第二題,不可能用到大數那麼複雜的東西,直接一位一位處理就好了。

XpXp-1...X2X1

      *                       t

      = X1XpXp-1...X2

先列舉X1然後,下面的X2就被算出來,再寫上去,依次計算就可以了。

詳見程式碼:

AC程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;

int a[1000005];
int b[1000005];

int main()
{
    int p,t;

    int i;
    int x;
    while(cin>>p>>t)
    {
        int flag=0;
        for(a[p]=1;a[p]<=9;a[p]++)
        {
            memset(b,0,sizeof(b));
            for(i=p;i>=2;i--)
            {
                b[i]+=a[i]*t;
                int t1=b[i]%10,t2=b[i]/10;
                a[i-1]=t1;
                b[i-1]=t2;
            }
            b[1]+=a[1]*t;
            if(a[p]==b[1]&&a[1]!=0)
            {
                flag=1;
                break;
            }
        }

        if(flag)
        {
            for(i=1;i<=p;i++)
                cout<<a[i];
            cout<<endl;
        }
        else
        {
            puts("Impossible");
        }
    }
    return 0;
}

然後再附上自己TLE的JAVA程式碼,畢竟寫了一個多小時,好久都沒碰java了。

import java.util.*;  
import java.math.*;  

public class Main {
    public static void main(String args[])  
    {  
         Scanner cin = new Scanner(System.in);  
         BigInteger y,q,mq,tq;
         BigInteger res;
         int p,t;
         int x;
         
         while(cin.hasNext())  
         {  
             p=cin.nextInt();  
             t=cin.nextInt();  
             int tmp=10;
             q=BigInteger.valueOf(tmp);
             
             res=BigInteger.ONE;
             q=q.pow(p-1);
             
             mq=BigInteger.valueOf(t);
             q=q.subtract(mq);
             //System.out.println(q);  
             
             
             int flag=0;
             for(x=1;x<=9;x++)
             {
                 tq=q;
                 mq=BigInteger.valueOf(x);
                 //mq=BigInteger.valueOf(10*t-1);
                 tq=tq.multiply(mq);
                 mq=BigInteger.valueOf(10*t-1);
                 /*if(x==7)
                 {
                     System.out.print(tq);  
                     System.out.print(" "); 
                    System.out.print(tq.divide(mq));  
                    System.out.print(" "); 
                    System.out.print(tq.remainder(mq)); 
                    System.out.println(" "); 
                 }*/
                 
                 if(tq.remainder(mq).equals(BigInteger.ZERO))
                 {
                     //System.out.print("hehhe");  
                     y=tq.divide(mq);
                     String ans=y.toString();
                     if(ans.length()==p-1)
                     {
                         flag=1;
                         res=y.multiply(BigInteger.valueOf(10)).add(BigInteger.valueOf(x));
                         break;
                     }
                 }
             }
             
             
             if(flag==1)
             {
                 System.out.println(res);  
                // System.out.println(ans.length());  
             }
             else
             {
                 System.out.println("Impossible");  
             }
         }  
    }  
}


C題:貪心

題目地址:http://codeforces.com/contest/394/problem/C

B題寫完就只有二十分鐘了,C題題面很少,但是還是沒讀懂。。不該把B題想那麼複雜。

C題就是有n*m個domino,每個domino有兩個球,裡面裝的0或者1,有n*m個domino現在,可以對這些domino重新放置使得每一縱列的1的最多個數最小。domino內部可以旋轉,比如01可以變成10.

我們可以先把domino裡面有兩個1的數出來,計數為p2,一個1的計數為p1,0個1的計數為p0,然後貪心。我們先放11的,一排一排的放,然後放一個1的,這時候兩排一起放。先放101010...下面就放010101...不過有一些細節需要注意,比如11的放到哪裡了,從哪裡開始。細節處理好就ok了,詳見程式碼:

AC程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;

char a[2005][2005];
char tmp[5];
int n,m;

void output()
{
    int i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=2;j++)
            printf("%c",a[i][j]);
        for(j=3;j<=2*m;j+=2)
            printf(" %c%c",a[i][j],a[i][j+1]);
        printf("\n");
    }
}

int main()
{
    int p2,p1,p0;
    int i,j;
    while(cin>>n>>m)
    {
        p2=p1=p0=0;   //統計個數
        for(i=0; i<n*m; i++)
        {
            cin>>tmp;
            if(tmp[0]=='1'&&tmp[1]=='1')
                p2++;
            else if(tmp[0]=='0'&&tmp[1]=='0')
                p0++;
            else p1++;
        }

        //cout<<p2<<" "<<p1<<" "<<p0<<endl;
        for(i=1;i<=n;i++)
            for(j=1;j<=2*m;j++)
                a[i][j]='0';
        //貪心實現
        int t=0;
        int pi,pj;

        if(p2>0)
        {
            for(i=1; i<=n; i++)
            {
                for(j=1; j<=2*m; j++)
                {
                    a[i][j]='1';
                    t++;
                    if(t==2*p2)
                    {
                        pi=i,pj=j;
                        break;
                    }
                }
                if(t==2*p2)
                    break;
            }
        }
        else
        {
            pi=0;
            pj=0;
        }
        //cout<<pi<<" "<<pj<<endl;
        //cout<<p1<<endl;

        t=0;
        int x=0;
        if(pj==2*m||pj==0)
        {
            for(i=pi+1; i<=n; i++)
            {
                if(t==p1)
                    break;
                if(x==0)
                {
                    for(j=1; j<=2*m; j+=2)
                    {
                        a[i][j]='1';
                        a[i][j+1]='0';
                        t++;
                        if(t==p1)
                        {
                            pi=i,pj=j;
                            break;
                        }
                    }
                    x=1;
                }
                else
                {
                    for(j=1; j<=2*m; j+=2)
                    {
                        a[i][j]='0';
                        a[i][j+1]='1';
                        t++;
                        if(t==p1)
                        {
                            pi=i,pj=j;
                            break;
                        }
                    }
                    x=0;
                }
                if(t==p1) break;
            }
        }
        else
        {
            t=0;
            while(1)
            {
                if(t==p1)
                    break;
                for(j=pj+1; j<=2*m; j+=2)
                {
                    a[pi][j]='1';
                    a[pi][j+1]='0';
                    t++;
                    if(t==p1)
                    {
                        pi=i,pj=j;
                        break;
                    }
                }
                if(t==p1) break;
                for(j=pj+1; j<=2*m; j+=2)
                {
                    a[pi+1][j]='0';
                    a[pi+1][j+1]='1';
                    t++;
                    if(t==p1)
                    {
                        pi=i,pj=j;
                        break;
                    }
                }
                if(t==p1) break;
                for(j=1; j<=pj; j+=2)
                {
                    a[pi+1][j]='0';
                    a[pi+1][j+1]='1';
                    t++;
                    if(t==p1)
                    {
                        pi=i,pj=j;
                        break;
                    }
                }
                if(t==p1) break;
                for(j=1; j<=pj; j+=2)
                {
                    a[pi+2][j]='1';
                    a[pi+2][j+1]='0';
                    t++;
                    if(t==p1)
                    {
                        pi=i,pj=j;
                        break;
                    }
                }
                if(t==p1) break;
                pi+=2;
            }
        }
        output();
    }
    return 0;
}

/*
2 3
01 11 00
00 01 11

4 1
11
10
01
00

1 1
00
*/


相關文章