[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 }
过河卒

 

posted @ 2016-10-17 18:08  SilverNebula  阅读(192)  评论(0编辑  收藏  举报
AmazingCounters.com