首页 > 代码库 > [NOIP2002] 普及组

[NOIP2002] 普及组

 

 

产生数

预处理出一个数能变成多少种数,然后遍历原串的每一位,累乘方案数即可。

需要用到高精度。

技术分享
 1 /*By SilverN*/ 2 #include<iostream> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cstring> 6 #include<cmath> 7 using namespace std; 8 char s[35]; 9 int ans[300],len;10 int num[10];11 int n;12 int mp[10][10];13 void mul(int x){14     int i;15     for(i=1;i<=len;i++){ans[i]=ans[i]*x;}16     for(i=1;i<=len;i++){17         if(ans[i]<10)continue;18         ans[i+1]+=ans[i]/10;19         ans[i]%=10;20     }21     while(ans[len]){22         ans[len+1]+=ans[len]/10;23         ans[len]%=10;24         len++;25     }26     return;27 }28 int main(){29     scanf("%s",s);30     int i,j;31     scanf("%d",&n);32     int u,v;33     for(i=1;i<=n;i++){34         scanf("%d%d",&u,&v);35         mp[u][v]=1;36     }37     for(i=0;i<=9;i++)mp[i][i]=1;38     for(int l=1;l<=9;l++)39         for(i=0;i<=9;i++)40              for(j=1;j<=9;j++)41                  mp[i][j]|=(mp[i][l]&mp[l][j]);//floyd判一个数字能转换成什么数字 42     for(i=0;i<=9;i++){43         int cnt=0;44         for(j=0;j<=9;j++)if(mp[i][j])cnt++;//累计方案数 45         num[i]=cnt; 46 //        printf("%d\n",num[i]);47     }48     int sl=strlen(s);49     ans[1]=1;len=1;50     for(i=0;i<sl;i++) mul(num[s[i]-0]);//累乘方案数 51     for(i=len-1;i;--i)printf("%d",ans[i]);52     return 0;53 }
产生数

 

选数

技术分享
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 struct xs{ 6     bool bo[50]; 7     int num[50]; 8 }x; 9 int sum=0,k,n,coun=0,ct=0;10 int pd(int p);11 int search(int t,int pos){12     for(int i=pos;i<=n;i++){13         if(!x.bo[i]){14             sum+=x.num[i];15             x.bo[i]=1;16             if(t>=k){17                 if(pd(sum)==1)coun++;18                     }19              else search(t+1,i+1);20             sum-=x.num[i];21             x.bo[i]=0;22         }23     }24 }25 26 int pd(int p){27     int i;28     if(p==2)return 1;29     for(i=2;i<=p/2;i++){30         if(p%i==0)return 0;31     }32     return 1;33 }34 int main(){35     memset(x.bo,0,sizeof(x.bo));36     memset(x.num,0,sizeof(x.num));37     int i;38     scanf("%d%d",&n,&k);39     for(i=1;i<=n;i++){40         scanf("%d",&x.num[i]);41     }42     search(1,1);43     printf("%d",coun);44     return 0;45 }
选数

搜索各种组合方式,注意判重。

 

级数求和

暴力模拟

技术分享
 1 /*By SilverN*/ 2 #include<iostream> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cstring> 6 #include<cmath> 7 using namespace std; 8 int n; 9 double smm,k;10 int main(){11     cin>>k;12     smm=0;13     n=1;14     while(n){15         smm+=(double)1/n;16         if(smm>k)break;17         n++;18     }19     cout<<n<<endl;20     return 0;21 }
级数求和

 

过河卒

暴力动规

技术分享
 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 const int mxn=30; 7 bool mp[mxn][mxn]; 8 long long f[mxn][mxn]; 9 int x1,y1,x2,y2;10 int main(){11     scanf("%d%d%d%d",&x1,&y1,&x2,&y2);12     x1+=3;x2+=3;y1+=3;y2+=3;13     f[2][3]=1;14     mp[x2][y2]=mp[x2-1][y2-2]=mp[x2+1][y2-2]=mp[x2-1][y2+2]=mp[x2+1][y2+2]=15         mp[x2-2][y2+1]=mp[x2-2][y2-1]=mp[x2+2][y2-1]=mp[x2+2][y2+1]=1;16     for(int i=3;i<=x1;i++)17      for(int j=3;j<=y1;j++){18          if(mp[i][j])mp[i][j]=0;19          else f[i][j]=f[i-1][j]+f[i][j-1];20     }21     printf("%lld\n",f[x1][y1]);22     return 0;23 }
过河卒

 

[NOIP2002] 普及组