Gym 101243 (2016-2017 ACM Central Region of Russia Quarterfinal Programming Contest)

来源:互联网 发布:淘宝上货助手 编辑:程序博客网 时间:2024/05/29 12:36

Problem A B C D E G H are included.

A. Fried Fish

题意:

         N 条鱼要煎熟,每次煎鱼锅中只能煎 K 条鱼的一面(一条鱼要煎两面),问最少要煎几次?

思路:

         由于一次只能煎鱼身的一面,故最少要煎两次。max(2,ceil(n*2/k))即可

代码:

#include <bits/stdc++.h>using namespace std;int main(){    double n,m;    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    while(cin>>n>>m){        cout<<max(ceil(n*2.0/m),2.0)<<endl;    }}

B. Hanoi tower

题意:

         本题题意与样例似乎有矛盾,我觉得题目应该是这样的:

         问 N 个盘子的汉诺塔,在第几次移动时,三根柱子上的盘子数一样。保证 N%3==0。

         当 N == 3的时候,答案是 2。

思路:

         先跑一边汉诺塔,打表找规律。发现

         A[3] = 2 , A[6] = 9

         当 N 是奇数时 A[N] = A[N-3] * 4 + 2

         当 N 是偶数时 A[N] = A[N-3] * 4 -TMP[N];TMP[12]=17 TMP[N]=TMP[N-6]*4+21;

代码:

汉诺塔:

#include <iostream>#include <stdio.h>using namespace std;long long ans;string steps;int cut[3];bool flag;string add(string str1,string str2){    int len1=str1.size();    int len2=str2.size();    if(len1<len2){        swap(str1,str2);        swap(len1,len2);    }    int c=0;    for(int i=len1-1,j=len2-1;i>=0;i--,j--){        int temp=0;        if(j>=0)            temp+=str2[j]-'0';        temp+=str1[i]+c-'0';        str1[i]=temp%10+'0';        c=temp/10;    }    if(c)        str1='1'+str1;    return str1;}void judge(){    if(cut[0]==cut[1]&&cut[1]==cut[2]){cout<<steps<<endl;flag=0;}}int move(int x,char a,char b){    cut[a-'A']--;cut[b-'A']++;    steps=add(steps,"1");judge();    //for(int i=0;i<3;i++)        //cout<<cut[i]<<endl;    //printf("number..%d..form..%c..to..%c\n",x,a,b);}int mission(int x,char a,char b,char c){    if(!flag) return 0;    if(x==1)    move(1,a,c);    else    {        mission(x-1,a,c,b);//将x-1从a借c移到b。        move(x,a,c);        mission(x-1,b,a,c);//将x-1从b借a移到c。    }    return 0;}int main(){    int n;    for(int i=1;i<=100;i++)    {        n=i*3;        flag=1;        steps="0";        cut[0]=n;cut[1]=cut[2]=0;        mission(n,'A','B','C');    }    return 0;}
递推:

import java.math.*;import java.util.*;import java.io.*;public class main {public static void main(String[] args) {//FOR First JAVA AC 2333333333try{Scanner cin = new Scanner(new File("input.txt"));FileWriter out = new FileWriter(new File("output.txt"));int n;File file = new File("INPUT.TXT");BigInteger ans[] = new BigInteger[200];ans[1] = new BigInteger("2");ans[2] = new BigInteger("9");BigInteger FOUR = new BigInteger("4");BigInteger TWO = new BigInteger("2");BigInteger TMP = new BigInteger("17");BigInteger TW = new BigInteger("21");for(int i=3;i<=100;i++){ans[i]=ans[i-1].multiply(FOUR);if(i%2==1){ans[i]=ans[i].add(TWO);}else{ans[i]=ans[i].subtract(TMP);TMP=TMP.multiply(FOUR);TMP=TMP.add(TW);}}while(cin.hasNext()){n = cin.nextInt();out.write(ans[n/3].toString());}out.close();}catch(Exception e){}}}

C. Desktop

题意:

        给出一个 N × M 的矩阵,用2×2的矩阵去覆盖它,覆盖的矩阵可以重叠但至少需要露出一半的面积。询问最大能放多少个2×2矩阵并且给出一种方案 

思路:

        很容易想到类似鱼鳞形状的铺法层铺。但要使数量最多,存在两个问题(以每一行作为铺设方向为例)

        1.若行数或列数为奇数,直接鱼鳞状铺法只能浪费掉一行或一列。所以我们要把奇数行或奇数列两两间不重叠地铺好。

        2.铺好后最后一层会有浪费,故最后一层要反向地铺。即若是以行铺,那最后一层以列铺,若是以列铺,那最后一层以行铺

#include<bits/stdc++.h>using namespace std;#define MAXN 500010int cut,x[MAXN],y[MAXN];int main(){    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    int n,m;    while(cin>>n>>m){        if(n<2||m<2){cout<<0<<endl;continue;}        int cut=0;        if(m%2){            for(int i=1;i<n;i+=2){                cut++;x[cut]=i;y[cut]=m-1;            }            m--;        }        if(n%2){            for(int i=1;i<m;i+=2){                cut++;x[cut]=n-1;y[cut]=i;            }            n--;        }        for(int i=1;i<=n;i+=2){            for(int j=1;j<m-1;j++){                cut++;x[cut]=i;y[cut]=j;            }        }        for(int i=1;i<n;i++){            cut++;x[cut]=i;y[cut]=m-1;        }        cout<<cut<<endl;        for(int i=1;i<=cut;i++)            cout<<x[i]<<' '<<y[i]<<endl;    }}


D. Weather Station

题意:

        给出1个字符串,由8各方向组成,问按照字符串从左到右的顺序,能有几种不同的走法。

思路:

        小DP,显然要想形成不同的路径,只有在串中出现 NE,SE,NW,SW时才会发生。

        而每当出现这些子串时(以NE为例),我们有两种选择

             1.继承 NE 串前面的状态,将NE看成一步。

             2.继承 E 前面的状态,将 N E看成两步。

        这两种选择都要加入DP计算

代码:

#include <iostream>#include <cstring>#include <cstdio>#define mod 1000000007using namespace std;int main(){    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    char str[100005];    int ans[100005],len;    while(cin>>str)    {        ans[0]=ans[1]=1;        len=strlen(str);        for(int i=1;i<len;i++)        {            if((str[i]=='E'||str[i]=='W')&&(str[i-1]=='N'||str[i-1]=='S'))                ans[i+1]=(ans[i-1]+ans[i])%mod;            else                ans[i+1]=ans[i];        }        cout<<ans[len]<<endl;    }    return 0;}
E. Cupcakes

题意:

         N 个人以循环队列的方式要分吃 K 个蛋糕。给出每次第 i 个人最多吃 a[i] 个蛋糕(即每次可以吃1~a[i]),若轮到某个人时已经没有蛋糕了,那这个人要负责收拾桌子。

         现在。同学们希望让那个每次都要吃最多蛋糕的人收拾桌子,因为他每次不仅能吃的最多,且每次都要吃 a[i] 个。问其他同学是否可以齐心协力通过调节自己吃的量,使得那个吃的最多的人收拾桌子。
思路:

        由于每一轮同学们吃的蛋糕的量的范围是确定的,所以蛋糕的余量在某一轮的范围内,就可以做到,反之则不能。

代码:

#include <bits/stdc++.h>using namespace std;const int MAXN=1e5+100;long long a[MAXN],n,m,all;long long front,left1,left2,turn1,turn2,temp1,temp2,temp3;int pos;bool solve(){    if(pos<=m&&front>=m) return 1;    left1=m-front;left2=m-pos;    turn1=n+a[pos]-1;turn2=all;    temp3=0;    for(int i=1;;i++){        temp1=turn1*i;        temp2=turn2*i;        if(left2<temp1) return 0;        if(temp3>temp1) return 1;        else temp3=temp2;        if(temp2<left1) continue;        else return 1;    }}int main(){    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    ios::sync_with_stdio(false);    while(cin>>n>>m){        front=0;        all=0;        for(int i=0;i<n;i++){            cin>>a[i];            all+=a[i];        }        pos=max_element(a,a+n)-a;        for(int i=0;i<pos;i++)            front+=a[i];        if(solve()) cout<<"YES"<<endl;        else cout<<"KEK"<<endl;    }}
G. Sphenic numbers

题意:

         给出一个数,问是否可以由三个(种?)质数相乘得到。

思路:

         若严格要求是三个质数,我的思路是打出质数后,暴力+剪枝完成.

         若只是要求是三种质数,跑一边素数筛,记录每个数被筛到的次数就行。

代码:

三个质数:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MAXN=1e7+100;int prime[(int)1e7+5];void getP(){    memset(prime,0,sizeof(prime));    for(int i=2; i<=MAXN; i++)    {        if(!prime[i])prime[++prime[0]]=i;        for(int j=1; j<=prime[0]&&prime[j]<=MAXN/i; j++)        {            prime[prime[j]*i]=1;            if(i%prime[j]==0) break;        }    }}bool t[11000000]={0};int main(){    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    int cur1=0,m;    getP();    for(int i=1;i<300000;i++)    {        if(prime[i]*prime[i]*prime[i]>10467397)            break;        for(int j=i+1;j<300000;j++)        {            if(prime[i]*prime[j]*prime[j]>10467397)                break;            for(int k=j+1;k<300000;k++)            {                if(prime[i]*prime[j]*prime[k]>10467397)                    break;                if(!t[prime[i]*prime[j]*prime[k]])                    t[prime[i]*prime[j]*prime[k]]=1;            }        }    }    while(cin>>m)    {        if(t[m])            cout<<"YES"<<endl;        else            cout<<"NO"<<endl;    }    return 0;}
三种质数:
#include <bits/stdc++.h>using namespace std;int main(){    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    int n;bool flag;    while(cin>>n){        int cut=0;        for(int i=2;i*i<=n;i++){            flag=1;            while(n%i==0){                if(flag){cut++;flag=0;}                n/=i;            }        }        if(n!=1) cut++;        if(cut==3) cout<<"YES"<<endl;        else cout<<"NO"<<endl;    }}
H. Non-random numbers

题意:

        求从左向右没有前置0,第一位不能有1,第二位不能有2........第九位不能有9的 N 位数的个数。

思路:

        规律题

代码:

#include <bits/stdc++.h>using namespace std;long long ans[10]={0};int n;int main(){    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    ans[1]=8;    for(int i=2;i<=9;i++) ans[i]=ans[i-1]*9;    while(cin>>n){        cout<<ans[min(9,n)];        for(int i=10;i<=n;i++) cout<<'0';        cout<<endl;    }}




0 0