• 【NOIP2008】提高组


    T1笨小猴

    题目链接

    开个桶统计,扫一遍记录min,max再O(sqrt(n))判合法就行了。

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<cstring>
     4 #include<algorithm>
     5 int ton[27],mni,mxa;
     6 char ch[105];
     7 bool check(int x){
     8     if(x<2)return 0;
     9     for(int i=2;i<=sqrt(x);i++)
    10         if(x%i==0)return 0;
    11     return 1;
    12 }
    13 int main(){
    14     scanf("%s",ch+1);
    15     int len=strlen(ch+1);
    16     for(int i=1;i<=len;i++)ton[ch[i]-'a'+1]++;
    17     mni=len;mxa=0;
    18     for(int i=1;i<=26;i++){
    19         if(!ton[i])continue;
    20         mni=std::min(ton[i],mni);
    21         mxa=std::max(ton[i],mxa);
    22     }
    23     int p=mxa-mni;
    24     if(check(p))
    25         printf("Lucky Word
    %d",p);
    26     else printf("No Answer
    0");
    27     return 0;
    28 }
    T1

    T2火柴棒等式

    题目链接

    n<=24直接上剪枝DFS即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 int n,sum=0,p;
     5 int count[10]={6,2,5,5,4,5,6,3,7,6};
     6 void dfs(int cc,int x,int k){
     7     int x0=x,num=0;
     8     if(!x0)num=6;
     9     while(x0){
    10         num+=count[x0%10];x0/=10;
    11     }
    12     if(num==k&&cc==3){sum++;return;}
    13     if(num>=k||cc==3)return;
    14     if(cc==1)for(int i=0;i<=1000;i++)dfs(2,i,k-num);
    15     else dfs(3,p+x,k-num);
    16 }
    17 int main(){
    18     scanf("%d",&n);
    19     n-=4;
    20     for(p=0;p<=1000;p++)dfs(1,p,n);
    21     printf("%d",sum);
    22     return 0;
    23 }
    T2

    T3传纸条

    题目链接

    看成是从左上角找两条除左上右下之外不相交的路径,

    那么就可以用f[i][j][x][y]表示走到(i,j)和(x,y)两个点的最大值。

    因为i,j,x,y知道其中三个就可以算出最后一个,因此数组只要开三维就够了。

    转移O(n3)。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 const int N=55;
     5 int n,m;
     6 int read(){
     7     int ans=0,f=1;char c=getchar();
     8     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     9     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    10     return ans*f;
    11 }
    12 int min(int x,int y){return x>y?y:x;}
    13 int max(int x,int y){return x<y?y:x;}
    14 int mp[N][N];
    15 int f[N][N][N];
    16 int main(){
    17     m=read();n=read();
    18     for(int i=1;i<=m;i++)
    19         for(int j=1;j<=n;j++)mp[i][j]=read();
    20     for(int i=1;i<=m;i++){
    21         for(int j=1;j<=n;j++){
    22             if(i==1&&j==1)continue;
    23             for(int x=1;x<=min(i+j,m);x++){
    24                 if(x==i&&(i!=m||j!=n))continue;
    25                 int y=i+j-x;
    26                 int&p=f[i][j][x];
    27                 p=f[i-1][j][x];
    28                 p=max(p,f[i-1][j][x-1]);
    29                 p=max(p,f[i][j-1][x]);
    30                 p=max(p,f[i][j-1][x-1]);
    31                 p+=mp[i][j]+mp[x][y];
    32             }
    33         }
    34     }
    35     printf("%d",f[m][n][m]);
    36     return 0;
    37 }
    T3

    T4双栈排序

    题目链接

    这道题的思想其实在后来的关押罪犯中有再次体现,说明历史还是会重复的=)

    用i和i+n表示对立的两个集合,每次要入栈时就枚举一下比它小的数在哪个栈里,尝试加入到另一个栈里,如果发现冲突就说明无解。

    因为要按选字典序最小的方案,所以能塞到第一个栈就塞进去。

    还有就是枚举完注意可能栈里还有元素因此要让站内元素出栈。

    然后,没了......

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define mem(a,p) memset(a,p,sizeof(a))
     5 const int N=1005;
     6 int read(){
     7     int an=0,f=1;char c=getchar();
     8     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     9     while(c>='0'&&c<='9'){an=an*10+c-48;c=getchar();}
    10     return an*f;
    11 }
    12 int n,mni,st[N*2],tot=0,fa[N*2],a[N];
    13 char an[N*2];
    14 bool ok[N*2];
    15 int getf(int x){return x==fa[x]?x:fa[x]=getf(fa[x]);}
    16 int main(){
    17     n=read();mni=1;
    18     for(int i=1;i<=n;i++)a[i]=read(),fa[i]=i,fa[i+n]=i+n;
    19     for(int i=1;i<=n;i++){
    20         while(mni<=n&&ok[mni]==1)ok[mni]=0,mni++;
    21         for(int j=1;j<a[i];j++){
    22             if(!ok[j])continue;
    23             int f1=getf(j),f2=getf(j+n);
    24             if(f1==a[i]||f2==a[i]+n)return printf("0
    "),0;
    25             fa[f1]=a[i]+n;fa[f2]=a[i];
    26         }
    27         ok[a[i]]=1;
    28     }
    29     mem(ok,0);mni=1;
    30     for(int i=1;i<=n;i++){
    31         while(mni<=n&&ok[mni])an[++tot]='a'+st[getf(mni)],mni++;
    32         int f1=getf(a[i]),f2=getf(a[i]+n);
    33         if(!st[f1])st[f1]=1,st[f2]=3;
    34         an[++tot]='a'+st[f1]-1;ok[a[i]]=1;
    35     }
    36     while(mni<=n&&ok[mni])an[++tot]='a'+st[getf(mni)],mni++;//这里别完了剩余元素出栈
    37     for(int i=1;i<tot;i++)printf("%c ",an[i]);printf("%c",an[tot]);
    38     return 0;
    39 }
    T4
  • 相关阅读:
    HR问“你目前有几个offer”,聪明人会怎么说?
    秋招还有 1 个月到达战场,请做好准备 !
    我人生中的第一场Java面试
    MZ头里面的东西。真他妈多
    特殊的一卦
    今天出门去办事,又倒霉了
    内核回调
    sys_call_table HOOK
    起一卦,看看情况
    我的简陋界面库的模块组成
  • 原文地址:https://www.cnblogs.com/JKAI/p/7788388.html
Copyright © 2020-2023  润新知