算法-藍橋杯習題(七)

藍橋杯習題html

藍橋杯練習系統習題加答案更新新地址(已更新200左右習題)ios

http://blog.csdn.net/rodestillfaraway c++

 


 

目錄算法

算法訓練(詳見 算法-藍橋杯習題(一))Gowindows

算法訓練(詳見 算法-藍橋杯習題(二))Gospa

算法提升(waiting...).net

歷屆試題(詳見 算法-藍橋杯習題(六))Gocode

歷屆試題(詳見 算法-藍橋杯習題(七))Gohtm

 


 

藍橋杯練習系統評測數據blog

連接:

http://pan.baidu.com/s/1mhophTQ

密碼: m2pa

 


 

歷屆試題(PartC-14題)

 

 1 /*
 2 歷屆試題 迴文數字
 3 
 4 問題描述
 5   觀察數字:12321,123321 都有一個共同的特徵,不管從左到右讀仍是從右向左讀,都是相同的。這樣的數字叫作:迴文數字。
 6 
 7   本題要求你找到一些5位或6位的十進制數字。知足以下要求:
 8   該數字的各個數位之和等於輸入的整數。
 9 輸入格式
10   一個正整數 n (10<n<100), 表示要求知足的數位和。
11 輸出格式
12   若干行,每行包含一個知足要求的5位或6位整數。
13   數字按從小到大的順序排列。
14   若是沒有知足條件的,輸出:-1
15 樣例輸入
16 44
17 樣例輸出
18 99899
19 499994
20 589985
21 598895
22 679976
23 688886
24 697796
25 769967
26 778877
27 787787
28 796697
29 859958
30 868868
31 877778
32 886688
33 895598
34 949949
35 958859
36 967769
37 976679
38 985589
39 994499
40 樣例輸入
41 60
42 樣例輸出
43 -1
44 */
45 
46 #include<stdio.h>
47 int main()
48 {
49     int a,b,c;
50     int n;
51     int flag=-1;
52     scanf("%d",&n);
53     
54     for(a=1;a<10;a++)
55     {
56         for(b=0;b<10;b++)
57         {
58             for(c=0;c<10;c++)
59             {
60                 if(a+b+c+b+a==n)
61                 {
62                     flag=1;
63                     printf("%d%d%d%d%d\n",a,b,c,b,a);
64                 }
65             }
66         }
67     }
68 
69     for(a=1;a<10;a++)
70     {
71         for(b=0;b<10;b++)
72         {
73             for(c=0;c<10;c++)
74             {
75                 if(a+b+c+c+b+a==n)
76                 {
77                     printf("%d%d%d%d%d%d\n",a,b,c,c,b,a);
78                     flag=1;
79                 }
80             }
81         }
82     }
83     if(flag==-1)
84         printf("%d\n",flag);
85     return 0;
86 }
  1 /*
  2 歷屆試題 國王的煩惱
  3 
  4 問題描述
  5   C國由n個小島組成,爲了方便小島之間聯絡,C國在小島間創建了m座大橋,每座大橋鏈接兩座小島。兩個小島間可能存在多座橋鏈接。然而,因爲海水沖刷,有一些大橋面臨着不能使用的危險。
  6 
  7   若是兩個小島間的全部大橋都不能使用,則這兩座小島就不能直接到達了。然而,只要這兩座小島的居民能經過其餘的橋或者其餘的小島互相到達,他們就會安然無事。可是,若是前一天兩個小島之間還有方法能夠到達,後一天卻不能到達了,居民們就會一塊兒抗議。
  8 
  9   如今C國的國王已經知道了每座橋能使用的天數,超過這個天數就不能使用了。如今他想知道居民們會有多少天進行抗議。
 10 輸入格式
 11   輸入的第一行包含兩個整數n, m,分別表示小島的個數和橋的數量。
 12   接下來m行,每行三個整數a, b, t,分別表示該座橋鏈接a號和b號兩個小島,能使用t天。小島的編號從1開始遞增。
 13 輸出格式
 14   輸出一個整數,表示居民們會抗議的天數。
 15 樣例輸入
 16 4 4
 17 1 2 2
 18 1 3 2
 19 2 3 1
 20 3 4 3
 21 樣例輸出
 22 2
 23 樣例說明
 24   第一天後2和3之間的橋不能使用,不影響。
 25   次日後1和2之間,以及1和3之間的橋不能使用,居民們會抗議。
 26   第三天後3和4之間的橋不能使用,居民們會抗議。
 27 數據規模和約定
 28   對於30%的數據,1<=n<=20,1<=m<=100;
 29   對於50%的數據,1<=n<=500,1<=m<=10000;
 30   對於100%的數據,1<=n<=10000,1<=m<=100000,1<=a, b<=n, 1<=t<=100000。
 31 */
 32 #include<stdio.h>
 33 #include<malloc.h>
 34 int a[100001],b[100001],c[100001],d[10001];
 35 struct tubiao
 36 {
 37     int n;
 38     struct tubiao *next;
 39 }tu[10001];
 40 void add(int u,int v)
 41 {
 42     struct tubiao *p=(struct tubiao*) malloc(sizeof(struct tubiao));
 43     p->n=v;
 44     p->next=NULL;
 45     struct tubiao *q=&tu[u];
 46     while(q->next)
 47        {  q=q->next;
 48           
 49        }
 50     q->next=p;
 51 }
 52 void paixu(int first,int last)
 53 {  if(first<last)
 54      {
 55           int i=first,j=last,ka=a[first],kb=b[first],kc=c[first];
 56           while(i<j)
 57           {
 58               while(i<j&&kc<=c[j])
 59                   j--;
 60               a[i]=a[j];b[i]=b[j];c[i]=c[j];
 61               while(i<j&&kc>=c[i])
 62                   i++;
 63              a[j]=a[i];b[j]=b[i];c[j]=c[i];
 64              
 65          }
 66          a[i]=ka;b[i]=kb;c[i]=kc;
 67          paixu(first,i-1);
 68          paixu(i+1,last);
 69      }
 70     
 71 }
 72 int f1(int i)
 73 {
 74     if(d[i]==i)
 75       return i;
 76     int u=f1(d[i]);
 77     d[i]=u;
 78     return d[i];
 79 }
 80 int main()
 81 {
 82     int n,m,i1,u,v,t,i2;
 83     scanf("%d%d",&n,&m);
 84     for(i1=0;i1<m;i1++)
 85     {   scanf("%d%d%d",&u,&v,&t);
 86         a[i1]=u;b[i1]=v;c[i1]=t;
 87         add(u,v);
 88         add(v,u);
 89     }
 90     paixu(0,m-1);
 91     int  total=0,tianshu=0;
 92  for(i1=1;i1<=n;i1++)
 93     d[i1]=i1;
 94  for(i1=m-1;i1>=0;i1--)
 95  {     int ko=f1(a[i1]);
 96        int ok=f1(b[i1]);
 97       if(ko==ok)
 98           {
 99              continue;    
100           }
101       else 
102          {
103              d[ko]=b[i1];
104              if(tianshu!=c[i1])
105                 {
106                      total++;
107                      tianshu=c[i1];
108                    }
109                 
110          }
111  }
112   printf("%d\n",total);
113     return 0;
114 }
 1 /*
 2 歷屆試題 數字遊戲
 3 
 4 問題描述
 5   棟棟正在和同窗們玩一個數字遊戲。
 6 
 7   遊戲的規則是這樣的:棟棟和同窗們一共n我的圍坐在一圈。棟棟首先說出數字1。接下來,坐在棟棟左手邊的同窗要說下一個數字2。再下面的一個同窗要從上一個同窗說的數字往下數兩個數說出來,也就是說4。下一個同窗要往下數三個數,說7。依次類推。
 8 
 9   爲了使數字不至於太大,棟棟和同窗們約定,當在心中數到 k-1 時,下一個數字從0開始數。例如,當k=13時,棟棟和同窗們報出的前幾個數依次爲:
10   1, 2, 4, 7, 11, 3, 9, 3, 11, 7。
11 
12   遊戲進行了一下子,棟棟想知道,到目前爲止,他全部說出的數字的總和是多少。
13 輸入格式
14   輸入的第一行包含三個整數 n,k,T,其中 n 和 k 的意義如上面所述,T 表示到目前爲止棟棟一共說出的數字個數。
15 輸出格式
16   輸出一行,包含一個整數,表示棟棟說出全部數的和。
17 樣例輸入
18 3 13 3
19 樣例輸出
20 17
21 樣例說明
22   棟棟說出的數依次爲1, 7, 9,和爲17。
23 數據規模和約定
24   1 < n,k,T < 1,000,000;
25 */
26 #include <stdio.h>
27 #include <windows.h>3 
28 int s[1000000];
29 // 3  13  9 
30 //  1 2 4 7 11 3 9 3 11 7 4 2 1    1 2 4 7 11 3 9 3 11 7 4 2 1 
31 int main()
32 {
33 long long n,k,t,i,j=1,g=1,z,sum=0;
34 scanf("%I64d%I64d%I64d",&n,&k,&t);
35 if(k%2==0) z=k*2;
36 else z=k;
37 s[0]=1;
38 do    //開始製表 
39 {
40 j+=g;
41 if(j>=k) j%=k; 
42 s[g]=j;
43 g++;     
44 }                         
45 while(g<=z) ; 
46 k=0;      
47 for(i=0;i<t;i++)
48 {
49  sum+=s[k];
50  k+=n;
51  if(k>g-1) k-=g-1;             
52 }                 
53 
54                 
55 printf("%I64d",sum);
56 system("pause");
57  return 0;   
58 }
  1 /*
  2 歷屆試題 郵局
  3 
  4 問題描述
  5   C村住着n戶村民,因爲交通閉塞,C村的村民只能經過信件與外界交流。爲了方便村民們發信,C村打算在C村建設k個郵局,這樣每戶村民能夠去離本身家最近的郵局發信。
  6 
  7   如今給出了m個備選的郵局,請從中選出k個來,使得村民到本身家最近的郵局的距離和最小。其中兩點之間的距離定義爲兩點之間的直線距離。
  8 輸入格式
  9   輸入的第一行包含三個整數n, m, k,分別表示村民的戶數、備選的郵局數和要建的郵局數。
 10   接下來n行,每行兩個整數x, y,依次表示每戶村民家的座標。
 11   接下來m行,每行包含兩個整數x, y,依次表示每一個備選郵局的座標。
 12   在輸入中,村民和村民、村民和郵局、郵局和郵局的座標可能相同,但你應把它們當作不一樣的村民或郵局。
 13 輸出格式
 14   輸出一行,包含k個整數,從小到大依次表示你選擇的備選郵局編號。(備選郵局按輸入順序由1到m編號)
 15 樣例輸入
 16 5 4 2
 17 0 0
 18 2 0
 19 3 1
 20 3 3
 21 1 1
 22 0 1
 23 1 0
 24 2 1
 25 3 2
 26 樣例輸出
 27 2 4
 28 數據規模和約定
 29   對於30%的數據,1<=n<=10,1<=m<=10,1<=k<=5;
 30   對於60%的數據,1<=m<=20;
 31   對於100%的數據,1<=n<=50,1<=m<=25,1<=k<=10。
 32 */
 33 #include <stdio.h>
 34 #include <math.h>
 35 
 36 using namespace std;
 37 
 38 struct Point {
 39     int no;
 40     int x, y;
 41 
 42     double getDist(Point p) {
 43         return sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));
 44     }
 45 };
 46 
 47 Point ans[10];
 48 int n, m, k;
 49 Point person[50];
 50 Point fire[25];
 51 Point result[10];
 52 bool repeat[50], ban[50];
 53 double ansDist = 1000000000;
 54 double minDist[50], sum = 0;
 55 double G[50][25];
 56 
 57 void dfs(int deep, int index)
 58 {
 59     if(deep == k) {
 60         if(sum < ansDist) {
 61             ansDist = sum;
 62             for(int i = 0; i < k; i++) {
 63                 ans[i] = result[i];
 64             }
 65         }
 66     } else {
 67         double tmpDist[50] = {0}, tsum = sum;
 68         bool flag2 = false;
 69         for(int i = 0; i < n; i++)
 70             tmpDist[i] = minDist[i];
 71         for(int i = m-k+deep; i >= index; i--) {
 72             if(repeat[i]) continue;
 73             if(deep > 0 && ban[i]) continue;
 74             bool flag = false;
 75             if(deep == 0) {
 76                 sum = 0;
 77                 for(int j = 0; j < n; j++) {
 78                     minDist[j] = G[j][i];
 79                     sum += G[j][i];
 80                 }
 81                 flag = true;
 82             }
 83             else {
 84                 sum = tsum;
 85                 for(int j = 0; j < n; j++) {
 86                     if(G[j][i] < tmpDist[j]) {
 87                         sum -= tmpDist[j] - G[j][i];
 88                         minDist[j] = G[j][i];
 89                         flag = true;
 90                     } else minDist[j] = tmpDist[j];
 91                 }
 92             }
 93             if(flag) {
 94                 flag2 = true;
 95                 result[deep] = fire[i];
 96                 dfs(deep+1, result[deep].no + 1);
 97             } else {
 98                 ban[i] = true;
 99             }
100         }
101         if(flag2 == false) {
102             result[deep] = fire[result[deep-1].no+1];
103             dfs(deep+1, m-k+deep+1);
104         } else {
105             sum = tsum;
106             for(int j = 0; j < n; j++) {
107                 minDist[j] = tmpDist[j];
108             }
109         }
110     }
111 }
112 
113 int main()
114 {
115     scanf("%d%d%d", &n, &m, &k);
116     for(int i = 0; i < n; i++) {
117         scanf("%d%d", &person[i].x, &person[i].y);
118         minDist[i] = ansDist;
119     }
120     for(int i = 0; i < m; i++) {
121         scanf("%d%d", &fire[i].x, &fire[i].y);
122         fire[i].no = i;
123     }
124     for(int i = 0; i < m; i++) {
125         if(!repeat[i]) {
126             for(int j = i+1; j < m; j++)
127                 if(fire[i].x == fire[j].x && fire[i].y == fire[j].y)
128                     repeat[j] = true;
129         }
130     }
131     for(int i = 0; i < n; i++)
132         for(int j = 0; j < m; j++)
133             G[i][j] = person[i].getDist(fire[j]);
134     dfs(0, 0);
135     for(int i = 0; i < k; i++) {
136         printf("%d ", ans[i].no+1);
137     }
138     return 0;
139 }
  1 /*
  2 歷屆試題 城市建設
  3 
  4 問題描述
  5   棟棟居住在一個繁華的C市中,然而,這個城市的道路大都年久失修。市長準備從新修一些路以方便市民,因而找到了棟棟,但願棟棟能幫助他。
  6 
  7   C市中有n個比較重要的地點,市長但願這些地點重點被考慮。如今能夠修一些道路來鏈接其中的一些地點,每條道路能夠鏈接其中的兩個地點。另外因爲C市有一條河從中穿過,也能夠在其中的一些地點建設碼頭,全部建了碼頭的地點能夠經過河道鏈接。
  8 
  9   棟棟拿到了容許建設的道路的信息,包括每條能夠建設的道路的花費,以及哪些地點能夠建設碼頭和建設碼頭的花費。
 10 
 11   市長但願棟棟給出一個方案,使得任意兩個地點能只經過新修的路或者河道互達,同時花費盡可能小。
 12 輸入格式
 13   輸入的第一行包含兩個整數n, m,分別表示C市中重要地點的個數和能夠建設的道路條數。全部地點從1到n依次編號。
 14   接下來m行,每行三個整數a, b, c,表示能夠建設一條從地點a到地點b的道路,花費爲c。若c爲正,表示建設是花錢的,若是c爲負,則表示建設了道路後還能夠賺錢(好比建設收費道路)。
 15   接下來一行,包含n個整數w_1, w_2, …, w_n。若是w_i爲正數,則表示在地點i建設碼頭的花費,若是w_i爲-1,則表示地點i沒法建設碼頭。
 16   輸入保證至少存在一個方法使得任意兩個地點能只經過新修的路或者河道互達。
 17 輸出格式
 18   輸出一行,包含一個整數,表示使得全部地點經過新修道路或者碼頭鏈接的最小花費。若是知足條件的狀況下還能賺錢,那麼你應該輸出一個負數。
 19 樣例輸入
 20 5 5
 21 1 2 4
 22 1 3 -1
 23 2 3 3
 24 2 4 5
 25 4 5 10
 26 -1 10 10 1 1
 27 樣例輸出
 28 9
 29 樣例說明
 30   建設第二、三、4條道路,在地點四、5建設碼頭,總的花費爲9。
 31 數據規模和約定
 32   對於20%的數據,1<=n<=10,1<=m<=20,0<=c<=20,w_i<=20;
 33   對於50%的數據,1<=n<=100,1<=m<=1000,-50<=c<=50,w_i<=50;
 34   對於70%的數據,1<=n<=1000;
 35   對於100%的數據,1 <= n <= 10000,1 <= m <= 100000,-1000<=c<=1000,-1<=w_i<=1000,w_i≠0。
 36 */
 37 #include<cstdio>
 38 #include<algorithm>
 39 using namespace std;
 40 const int NO=100006;
 41 const int INF=1000000000;
 42 struct R
 43 {
 44     int a,b,w;
 45 }r[NO*10];
 46 int fa[NO];
 47 int n,m,sum;
 48 void reset_fa()
 49 {
 50     for(int i=0;i<=n;i++)
 51         fa[i]=i;
 52 }
 53 bool comp(const R &a,const R &b){return a.w<b.w;}
 54 int find(int k){return k==fa[k]?k:fa[k]=find(fa[k]);}
 55 int kruskal()
 56 {
 57     int i,num=0,a,b,k;
 58     for(i=1;i<=m;i++)
 59     {
 60         a=find(r[i].a);
 61         b=find(r[i].b);
 62         if(a!=b)
 63         {
 64             if(r[i].a==0)
 65             {
 66                 num++;
 67                 k=r[i].w;
 68             }
 69             sum+=r[i].w;
 70             fa[a]=b;
 71         }
 72     }
 73     if(num==1)
 74     {
 75         sum-=k;
 76     }
 77     return sum;
 78 }
 79 int main()
 80 {
 81     int i=1,j,a,b;
 82     scanf("%d%d",&n,&m);
 83     reset_fa();
 84     while(m--)
 85     {
 86         scanf("%d%d%d",&r[i].a,&r[i].b,&r[i].w);
 87         if(r[i].w<0)
 88         {
 89             sum+=r[i].w;
 90             a=find(r[i].a);
 91             b=find(r[i].b);
 92             if(a!=b)
 93                 fa[a]=b;
 94         }
 95         else
 96             i++;
 97     }
 98     for(j=1;j<=n;j++)
 99     {
100         scanf("%d",&a);
101         if(a!=-1)
102         {
103             r[++i].a=0;
104             r[i].b=j;
105             r[i].w=a;
106         }
107     }
108     m=i;
109     sort(r+1,r+1+m,comp);
110     printf("%d\n",kruskal());
111     return 0;
112 }
/*
歷屆試題 最大子陣

問題描述
  給定一個n*m的矩陣A,求A中的一個非空子矩陣,使這個子矩陣中的元素和最大。

  其中,A的子矩陣指在A中行和列均連續的一塊。
輸入格式
  輸入的第一行包含兩個整數n, m,分別表示矩陣A的行數和列數。
  接下來n行,每行m個整數,表示矩陣A。
輸出格式
  輸出一行,包含一個整數,表示A中最大的子矩陣中的元素和。
樣例輸入
3 3
-1 -4 3
3 4 -1
-5 -2 8
樣例輸出
10
樣例說明
  取最後一列,和爲10。
數據規模和約定
  對於50%的數據,1<=n, m<=50;
  對於100%的數據,1<=n, m<=500,A中每一個元素的絕對值不超過5000。
*/
#include "stdio.h"
#include "string.h"
int a[500][500],b[500];
int f(int n,int m)
{int i,j,k,t,max=-999999;
for(i=0;i<n;i++)
  {memset(b,0,m*sizeof(int));
   
    for(j=i;j<n;j++)
    {t=-999999;
    for(k=0;k<m;k++)
     {b[k]+=a[j][k];
       t+=b[k];
       if(t<b[k])t=b[k];
       if(max<t)max=t;    
     }    
    }
    
    
  }
  return max;
}
int main()
{
    int i,j,n,m;
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++)
    for(j=0;j<m;j++)
    scanf("%d",&a[i][j]);
    
    printf("%d",f(n,m));

    return 0;
}
  1 /*
  2 歷屆試題 螞蟻感冒
  3 
  4 問題描述
  5   長100釐米的細長直杆子上有n只螞蟻。它們的頭有的朝左,有的朝右。
  6 
  7   每隻螞蟻都只能沿着杆子向前爬,速度是1釐米/秒。
  8 
  9   當兩隻螞蟻碰面時,它們會同時掉頭往相反的方向爬行。
 10 
 11   這些螞蟻中,有1只螞蟻感冒了。而且在和其它螞蟻碰面時,會把感冒傳染給碰到的螞蟻。
 12 
 13   請你計算,當全部螞蟻都爬離杆子時,有多少隻螞蟻患上了感冒。
 14 輸入格式
 15   第一行輸入一個整數n (1 < n < 50), 表示螞蟻的總數。
 16 
 17   接着的一行是n個用空格分開的整數 Xi (-100 < Xi < 100), Xi的絕對值,表示螞蟻離開杆子左邊端點的距離。正值表示頭朝右,負值表示頭朝左,數據中不會出現0值,也不會出現兩隻螞蟻佔用同一位置。其中,第一個數據表明的螞蟻感冒了。
 18 輸出格式
 19   要求輸出1個整數,表示最後感冒螞蟻的數目。
 20 樣例輸入
 21 3
 22 5 -2 8
 23 樣例輸出
 24 1
 25 樣例輸入
 26 5
 27 -10 8 -20 12 25
 28 樣例輸出
 29 3
 30 */
 31 #include <stdio.h>
 32 struct mayi
 33 {
 34     int direct;  //0爲左,1爲右 
 35     int dist;   //距離左端點距離 
 36     int cold;  //0爲正常,1爲感冒     
 37 } ;
 38 
 39 int main()
 40 {
 41 int n,i,sign,j,num=0;
 42 scanf("%d",&n);
 43 struct mayi a[n];
 44 for(i=0;i<n;i++)
 45 {
 46 scanf("%d",&a[i].dist);
 47 a[i].dist*=2;
 48 a[i].direct=1;
 49 a[i].cold=0;
 50 if(a[i].dist<0) 
 51 {
 52     a[i].dist*=-1;
 53     a[i].direct=0;    
 54 }    
 55 a[0].cold=1;    
 56 } 
 57     
 58     for(;;)
 59    {
 60        sign=0;
 61          for(i=0;i<n;i++)  //全部螞蟻走路 
 62            {
 63                if(a[i].direct==0) a[i].dist--;
 64                else a[i].dist++;
 65            } 
 66    
 67            for(i=0;i<n-1;i++)
 68           for(j=i+1;j<n;j++)
 69            {
 70         if(a[i].dist==a[j].dist)
 71         {
 72             if(a[i].direct==0) 
 73             {a[i].direct=1;    }
 74             else a[i].direct=0;
 75             
 76             if(a[j].direct==0)
 77             { a[j].direct=1;}
 78             else a[j].direct=0;
 79             
 80             if(a[i].cold==1 ) a[j].cold=1; 
 81             
 82             if(a[j].cold==1 ) a[i].cold=1; 
 83             
 84           }
 85         }
 86    
 87        for(i=0;i<n;i++)
 88       {
 89          if(a[i].dist>=0 && a[i].dist<=200)
 90           {
 91            sign=1;
 92            break;
 93            
 94          }
 95         
 96        }
 97    
 98         if(sign==0) break;
 99    
100   }
101     for(i=0;i<n;i++)
102     {
103         
104         if(a[i].cold==1) num++;
105     }
106 
107     printf("%d\n",num);
108 
109     return 0;
110 } 
  1 /*
  2 歷屆試題 地宮取寶
  3 
  4 問題描述
  5   X 國王有一個地宮寶庫。是 n x m 個格子的矩陣。每一個格子放一件寶貝。每一個寶貝貼着價值標籤。
  6 
  7   地宮的入口在左上角,出口在右下角。
  8 
  9   小明被帶到地宮的入口,國王要求他只能向右或向下行走。
 10 
 11   走過某個格子時,若是那個格子中的寶貝價值比小明手中任意寶貝價值都大,小明就能夠拿起它(固然,也能夠不拿)。
 12 
 13   當小明走到出口時,若是他手中的寶貝剛好是k件,則這些寶貝就能夠送給小明。
 14 
 15   請你幫小明算一算,在給定的局面下,他有多少種不一樣的行動方案能得到這k件寶貝。
 16 輸入格式
 17   輸入一行3個整數,用空格分開:n m k (1<=n,m<=50, 1<=k<=12)
 18 
 19   接下來有 n 行數據,每行有 m 個整數 Ci (0<=Ci<=12)表明這個格子上的寶物的價值
 20 輸出格式
 21   要求輸出一個整數,表示正好取k個寶貝的行動方案數。該數字可能很大,輸出它對 1000000007 取模的結果。
 22 樣例輸入
 23 2 2 2
 24 1 2
 25 2 1
 26 樣例輸出
 27 2
 28 樣例輸入
 29 2 3 2
 30 1 2 3
 31 2 1 5
 32 樣例輸出
 33 14
 34 */
 35 #include<stdio.h>
 36 #include<string.h>
 37 
 38 #define N 55
 39 #define MOD  1000000007
 40 
 41 int map[55][55];
 42 int dp[55][55][15][15];
 43 
 44 int main(void)
 45 {
 46     int n, m, k;
 47     int i, j, c, val, aMax;
 48     scanf("%d%d%d", &n, &m, &k);
 49     aMax = 0;
 50     for(i = 1; i <= n; i++)
 51     {
 52         for(j = 1; j <= m; j++)
 53         {
 54             scanf("%d", &map[i][j]);
 55 //            map[i][j]++;
 56             if(aMax < map[i][j])
 57             {
 58                 aMax = map[i][j];
 59             }
 60         }
 61     }
 62     memset(dp, 0, sizeof(dp));
 63     dp[1][1][0][0] = 1;
 64     dp[1][1][1][map[1][1]] = 1;
 65     for(i = 1; i <= n; i++)
 66     {
 67         for(j = 1; j <= m; j++)
 68         {
 69             dp[i][j][0][0] += dp[i][j - 1][0][0] + dp[i - 1][j][0][0];
 70             dp[i][j][0][0] %= MOD;
 71             for(c = 1; c <= k; c++)
 72             {
 73                 for(val = 0; val <= aMax; val++)
 74                 {
 75                     dp[i][j][c][val] += dp[i][j - 1][c][val] + dp[i - 1][j][c][val];
 76                     dp[i][j][c][val] %= MOD;
 77                 }
 78                 if(c == 1)
 79                 {
 80                     dp[i][j][1][map[i][j]] += dp[i][j - 1][0][0];
 81                     dp[i][j][1][map[i][j]] %= MOD;
 82                     dp[i][j][1][map[i][j]] += dp[i - 1][j][0][0];
 83                     dp[i][j][1][map[i][j]] %= MOD;
 84                 }
 85                 else
 86                 {
 87                     for(val = 0; val < map[i][j]; val++)
 88                     {
 89                         dp[i][j][c][map[i][j]] += dp[i][j - 1][c - 1][val];
 90                         dp[i][j][c][map[i][j]] %= MOD;
 91                         dp[i][j][c][map[i][j]] += dp[i - 1][j][c - 1][val];
 92                         dp[i][j][c][map[i][j]] %= MOD;
 93                     }
 94                 }
 95             }
 96         }
 97     }
 98     
 99     int sum = 0;
100     for(i = 0; i <= aMax; i++)
101     {
102         sum += dp[n][m][k][i];
103         sum %= MOD;
104     }
105     printf("%d", sum);
106     return 0;
107 }
  1 /*
  2 歷屆試題 斐波那契
  3 
  4 問題描述
  5   斐波那契數列你們都很是熟悉。它的定義是:
  6 
  7   f(x) = 1 .... (x=1,2)
  8   f(x) = f(x-1) + f(x-2) .... (x>2)
  9 
 10   對於給定的整數 n 和 m,咱們但願求出:
 11   f(1) + f(2) + ... + f(n) 的值。但這個值可能很是大,因此咱們把它對 f(m) 取模。
 12   公式以下
 13         圖片百度 
 14 
 15   但這個數字依然很大,因此須要再對 p 求模。
 16 輸入格式
 17   輸入爲一行用空格分開的整數 n m p (0 < n, m, p < 10^18)
 18 輸出格式
 19   輸出爲1個整數,表示答案
 20 樣例輸入
 21 2 3 5
 22 樣例輸出
 23 0
 24 樣例輸入
 25 15 11 29
 26 樣例輸出
 27 25
 28 */
 29 #include <map>
 30 #include <set>
 31 #include <list>
 32 #include <cmath>
 33 #include <ctime>
 34 #include <deque>
 35 #include <queue>
 36 #include <stack>
 37 #include <bitset>
 38 #include <cctype>
 39 #include <cstdio>
 40 #include <string>
 41 #include <vector>
 42 #include <cstdlib>
 43 #include <cstring>
 44 #include <iomanip>
 45 #include <sstream>
 46 #include <iostream>
 47 #include <algorithm>
 48 
 49 using namespace std;
 50 
 51 #define PB push_back
 52 #define MP make_pair
 53 #define AA first
 54 #define BB second
 55 #define OP begin()
 56 #define ED end()
 57 #define SZ size()
 58 #define SORT(x) sort(x.OP,x.ED)
 59 #define SQ(x) ((x)*(x))
 60 #define SSP system("pause")
 61 #define cmin(x,y) x=min(x,y)
 62 #define cmax(x,y) x=max(x,y)
 63 typedef long long LL;
 64 typedef pair<int, int> PII;
 65 const double eps=1e-8;
 66 const double INF=1e20;
 67 const double PI=acos( -1. );
 68 const int MXN = 50;
 69 const LL MOD = 1000000007;
 70 LL llmul( LL a,LL b,LL mod ) {
 71     a%=mod;a+=mod;a%=mod;
 72     b%=mod;b+=mod;b%=mod;
 73     if ( a<b )swap( a,b );
 74     LL ret=0;
 75     while ( b ) {
 76         if ( b&1 )ret=( ret+a )%mod;
 77         a=( a<<1 )%mod;
 78         b/=2;
 79     }
 80     return ret;
 81 }
 82 struct matrix {
 83     LL x[3][3];
 84     matrix() {memset( x,0,sizeof x );}
 85 };
 86 matrix mmul( matrix &A,matrix &B,LL mod ) {
 87     matrix ret;
 88     for ( int i=1; i<=2; i++ )
 89         for ( int j=1; j<=2; j++ )
 90             for ( int k=1; k<=2; k++ )
 91                 ret.x[i][j]=( ret.x[i][j]+llmul( A.x[i][k],B.x[k][j],mod ) )%mod;
 92     return ret;
 93 }
 94 matrix E;
 95 matrix A;
 96 LL fib( LL n,LL mod ) {
 97     matrix O=E,B=A;
 98     while ( n ) {
 99         if ( n&1 )O=mmul( O,B,mod );
100         B=mmul( B,B,mod );
101         n/=2;
102     }
103     return O.x[1][2];
104 }
105 
106 LL solve( LL n,LL m,LL mod ) {
107 
108     LL t=n/m;
109 
110     LL p=t/2,q=t%2;
111 
112     LL fuhao=p*m%2==0?1:-1;
113     if ( q==0 ) {
114         LL ans=fib( n%m,mod )*fuhao;
115         ans%=mod;
116         ans+=mod;
117         return ans%mod;
118     }
119     if ( n%m==0 )return 0;
120 
121     LL x=(llmul(fib(n%m,mod),fib(m-1,mod),mod)*fuhao%mod+mod)%mod;
122     LL y=fib(m,mod);
123     LL a=fib(n%m-1,mod);
124     if(n%m%2==0)a--;
125     if(fuhao<0)a++;
126     a=(a%mod+mod)%mod;
127 
128     return ((x-llmul(a,y,mod))%mod+mod)%mod;
129 }
130 int main() {
131     int i,j;
132     A.x[1][2]=A.x[2][1]=A.x[2][2]=1;
133     E.x[1][1]=E.x[2][2]=1;
134     LL n,m,mod;
135     while ( cin>>n>>m>>mod )
136         cout<<( solve( n+2,m,mod )-1+mod )%mod<<endl;
137     return 0;
138 }
 1 /*
 2 歷屆試題 波動數列
 3 
 4 問題描述
 5   觀察這個數列:
 6   1 3 0 2 -1 1 -2 ...
 7 
 8   這個數列中後一項老是比前一項增長2或者減小3。
 9 
10   棟棟對這種數列很好奇,他想知道長度爲 n 和爲 s 並且後一項老是比前一項增長a或者減小b的整數數列可能有多少種呢?
11 輸入格式
12   輸入的第一行包含四個整數 n s a b,含義如前面說述。
13 輸出格式
14   輸出一行,包含一個整數,表示知足條件的方案數。因爲這個數很大,請輸出方案數除以100000007的餘數。
15 樣例輸入
16 4 10 2 3
17 樣例輸出
18 2
19 樣例說明
20   這兩個數列分別是2 4 1 3和7 4 1 -2。
21 數據規模和約定
22   對於10%的數據,1<=n<=5,0<=s<=5,1<=a,b<=5;
23   對於30%的數據,1<=n<=30,0<=s<=30,1<=a,b<=30;
24   對於50%的數據,1<=n<=50,0<=s<=50,1<=a,b<=50;
25   對於70%的數據,1<=n<=100,0<=s<=500,1<=a, b<=50;
26   對於100%的數據,1<=n<=1000,-1,000,000,000<=s<=1,000,000,000,1<=a, b<=1,000,000。
27 */
28 #define mod 100000007
29 int n,s,a,b,x[1001][1001],i,j,t;
30 fun()
31 {
32     while(x[i+1][t]>=mod)x[i+1][t]-=mod;
33 }
34 int main()
35 {
36     scanf("%d%d%d%d",&n,&s,&a,&b);
37     b%=n;
38     b*=-1;
39     while(b<0)b+=n;
40     a%=n;
41     s%=n;
42     while(s<0)s+=n;
43     for(i=0;i<n;i++)
44         for(j=0;j<n;j++)
45             x[i][j]=0;
46     x[1][a]=x[1][b]=1;
47     for(i=1;i<n-1;i++)
48         for(j=0;j<n;j++)
49         {
50             t=(j+a*(i+1))%n;
51             x[i+1][t]+=x[i][j];
52             fun();
53             t=(j+b*(i+1))%n;
54             if(t>=n)
55                 t-=n;
56             x[i+1][t]+=x[i][j];
57             fun();
58         }
59     printf("%d\n",x[n-1][s]);
60     return 0;
61 }
 1 /*
 2 歷屆試題 小朋友排隊
 3 
 4 問題描述
 5   n 個小朋友站成一排。如今要把他們按身高從低到高的順序排列,可是每次只能交換位置相鄰的兩個小朋友。
 6 
 7   每一個小朋友都有一個不高興的程度。開始的時候,全部小朋友的不高興程度都是0。
 8 
 9   若是某個小朋友第一次被要求交換,則他的不高興程度增長1,若是第二次要求他交換,則他的不高興程度增長2(即不高興程度爲3),依次類推。當要求某個小朋友第k次交換時,他的不高興程度增長k。
10 
11   請問,要讓全部小朋友按從低到高排隊,他們的不高興程度之和最小是多少。
12 
13   若是有兩個小朋友身高同樣,則他們誰站在誰前面是沒有關係的。
14 輸入格式
15   輸入的第一行包含一個整數n,表示小朋友的個數。
16   第二行包含 n 個整數 H1 H2 … Hn,分別表示每一個小朋友的身高。
17 輸出格式
18   輸出一行,包含一個整數,表示小朋友的不高興程度和的最小值。
19 樣例輸入
20 3
21 3 2 1
22 樣例輸出
23 9
24 樣例說明
25   首先交換身高爲3和2的小朋友,再交換身高爲3和1的小朋友,再交換身高爲2和1的小朋友,每一個小朋友的不高興程度都是3,總和爲9。
26 數據規模和約定
27   對於10%的數據, 1<=n<=10;
28   對於30%的數據, 1<=n<=1000;
29   對於50%的數據, 1<=n<=10000;
30   對於100%的數據,1<=n<=100000,0<=Hi<=1000000。
31 */
32 #include<stdio.h>
33 
34 int h[100100];
35 int un[100100];
36 
37 int b[1000100];
38 int reb[1000100];
39 
40 int Lowbit(int x){
41     return x&(x^(x-1));
42 }
43 
44 int sum(int bit[], int idx){
45     int ret = 0;
46     while(idx > 0){
47         ret += bit[idx];
48         idx -= Lowbit(idx);
49     }
50     return ret;
51 }
52 
53 void add(int bit[], int idx, int val){
54     while(idx < 1000100){
55         bit[idx] += val;
56         idx += Lowbit(idx);
57     }
58 }
59 
60 long long uVal[100100];
61 
62 int main(void){
63     int n, i;
64     scanf("%d", &n);
65     uVal[0] = 0;
66     for(i = 0; i < n; i++){
67         scanf("%d", &h[i]);
68         h[i]++;
69         uVal[i + 1] = uVal[i] + i + 1;
70         
71         un[i] += i - sum(b, h[i]);
72         add(b, h[i], 1);
73     }
74     long long ans = 0;
75     for(i = n - 1; i >= 0; i--){
76         un[i] += sum(reb, h[i] - 1);
77         add(reb, h[i], 1);
78         
79         ans += uVal[un[i]];
80     }
81     printf("%I64d\n", ans);
82     return 0;
83 }
 1 /*
 2 歷屆試題 分糖果
 3 
 4 問題描述
 5   有n個小朋友圍坐成一圈。老師給每一個小朋友隨機發偶數個糖果,而後進行下面的遊戲:
 6 
 7   每一個小朋友都把本身的糖果分一半給左手邊的孩子。
 8 
 9   一輪分糖後,擁有奇數顆糖的孩子由老師補給1個糖果,從而變成偶數。
10 
11   反覆進行這個遊戲,直到全部小朋友的糖果數都相同爲止。
12 
13   你的任務是預測在已知的初始糖果情形下,老師一共須要補發多少個糖果。
14 輸入格式
15   程序首先讀入一個整數N(2<N<100),表示小朋友的人數。
16   接着是一行用空格分開的N個偶數(每一個偶數不大於1000,不小於2)
17 輸出格式
18   要求程序輸出一個整數,表示老師須要補發的糖果數。
19 樣例輸入
20 3
21 2 2 4
22 樣例輸出
23 4
24 */
25 #include <stdio.h>
26 #include <malloc.h>
27 int count=0;
28 void f(int n,int *m)
29 {
30     int j,temp=m[0];
31     for(j=n-1;j>0;j--)
32         m[(j+1)%n]+=(m[j]/=2);
33     m[1]+=temp/2;
34     m[0]-=temp/2;
35     for(j=0;j<n;j++)
36     {
37         if(m[j]%2!=0)
38         {
39              m[j]++;
40              count++;
41         }
42     }
43 }
44 int jisuan(int n,int *m)
45 {
46     int j;
47     for(j=0;j<n-1;j++)
48         if(m[j]!=m[j+1]) return 0;
49     return 1;
50 }
51 int main()
52 {
53     int n,j;
54     scanf("%d",&n);
55     int *m=(int*)malloc(sizeof(int)*n);
56     for(j=0;j<n;j++)
57         scanf("%d",&m[j]);
58     do
59     {
60         f(n,m);
61     }
62     while(jisuan(n,m)!=1);
63     printf("%d",count);
64     return 0;
65 }
 1 /*
 2 歷屆試題 蘭頓螞蟻
 3 
 4 問題描述
 5 
 6     圖形百度 
 7   蘭頓螞蟻,是於1986年,由克里斯·蘭頓提出來的,屬於細胞自動機的一種。
 8 
 9   平面上的正方形格子被填上黑色或白色。在其中一格正方形內有一隻「螞蟻」。
10   螞蟻的頭部朝向爲:上下左右其中一方。
11 
12   螞蟻的移動規則十分簡單:
13   若螞蟻在黑格,右轉90度,將該格改成白格,並向前移一格;
14   若螞蟻在白格,左轉90度,將該格改成黑格,並向前移一格。
15 
16   規則雖然簡單,螞蟻的行爲卻十分複雜。剛剛開始時留下的路線都會有接近對稱,像是會重複,但不論起始狀態如何,螞蟻通過漫長的混亂活動後,會開闢出一條規則的「高速公路」。
17 
18   螞蟻的路線是很難事先預測的。
19 
20   你的任務是根據初始狀態,用計算機模擬蘭頓螞蟻在第n步行走後所處的位置。
21 輸入格式
22   輸入數據的第一行是 m n 兩個整數(3 < m, n < 100),表示正方形格子的行數和列數。
23   接下來是 m 行數據。
24   每行數據爲 n 個被空格分開的數字。0 表示白格,1 表示黑格。
25 
26   接下來是一行數據:x y s k, 其中x y爲整數,表示螞蟻所在行號和列號(行號從上到下增加,列號從左到右增加,都是從0開始編號)。s 是一個大寫字母,表示螞蟻頭的朝向,咱們約定:上下左右分別用:UDLR表示。k 表示螞蟻走的步數。
27 輸出格式
28   輸出數據爲兩個空格分開的整數 p q, 分別表示螞蟻在k步後,所處格子的行號和列號。
29 樣例輸入
30 5 6
31 0 0 0 0 0 0
32 0 0 0 0 0 0
33 0 0 1 0 0 0
34 0 0 0 0 0 0
35 0 0 0 0 0 0
36 2 3 L 5
37 樣例輸出
38 1 3
39 樣例輸入
40 3 3
41 0 0 0
42 1 1 1
43 1 1 1
44 1 1 U 6
45 樣例輸出
46 0 0
47 */
48 #include<stdio.h>
49 int a[1000][1000]={
50     0
51 };
52 char f(int i,char now)
53 {
54     if(i==0&&now=='U'||i==1&&now=='D')
55       return 'R';
56     else if(i==0&&now=='R'||i==1&&now=='L')
57       return 'D';
58     else if(i==0&&now=='D'||i==1&&now=='U')
59       return 'L';
60     else if(i==0&&now=='L'||i==1&&now=='R')
61        return 'U';
62     
63 }
64 int main()
65 {
66     int n,m,i1,i2,x,y,k;
67     char s;
68     scanf("%d%d",&n,&m);
69     for(i1=0;i1<n;i1++)
70        for(i2=0;i2<m;i2++)
71            scanf("%d",&a[i1][i2]);
72     scanf("%d%d",&x,&y);
73     getchar();
74     scanf("%c%d",&s,&k);
75     char now=s;
76     while(k--)
77     {  if(a[x][y]==0)
78            a[x][y]=1;
79        else 
80           a[x][y]=0;
81        
82        now=f(a[x][y],now);
83        if(now=='U')
84            x--;
85         else if(now=='D')
86             x++;
87        else if(now=='L')
88            y--;
89        else
90            y++;
91             
92     }  
93     printf("%d %d\n",x,y);
94     return 0;
95 }
  1 /*
  2 歷屆試題 矩陣翻硬幣
  3 
  4 問題描述
  5   小明先把硬幣擺成了一個 n 行 m 列的矩陣。
  6 
  7   隨後,小明對每個硬幣分別進行一次 Q 操做。
  8 
  9   對第x行第y列的硬幣進行 Q 操做的定義:將全部第 i*x 行,第 j*y 列的硬幣進行翻轉。
 10 
 11   其中i和j爲任意使操做可行的正整數,行號和列號都是從1開始。
 12 
 13   當小明對全部硬幣都進行了一次 Q 操做後,他發現了一個奇蹟——全部硬幣均爲正面朝上。
 14 
 15   小明想知道最開始有多少枚硬幣是反面朝上的。因而,他向他的好朋友小M尋求幫助。
 16 
 17   聰明的小M告訴小明,只須要對全部硬幣再進行一次Q操做,便可恢復到最開始的狀態。然而小明很懶,不肯意照作。因而小明但願你給出他更好的方法。幫他計算出答案。
 18 輸入格式
 19   輸入數據包含一行,兩個正整數 n m,含義見題目描述。
 20 輸出格式
 21   輸出一個正整數,表示最開始有多少枚硬幣是反面朝上的。
 22 樣例輸入
 23 2 3
 24 樣例輸出
 25 1
 26 數據規模和約定
 27   對於10%的數據,n、m <= 10^3;
 28   對於20%的數據,n、m <= 10^7;
 29   對於40%的數據,n、m <= 10^15;
 30   對於10%的數據,n、m <= 10^1000(10的1000次方)。
 31 */
 32 #include<stdio.h>
 33 #include<string.h>
 34 #define MAX 1000 + 10
 35 
 36 int  minu[MAX], sub[MAX], sq[MAX];
 37 int x;
 38 
 39 int main()
 40 {
 41     void sqrt_int ( char * , int ) ;  
 42     char n[MAX], m[MAX];  scanf ( "%s" , n ) ; scanf ("%s" , m ) ;
 43     int a[MAX], b[MAX], s[MAX], S[MAX]; int c, i, j, k, na, nb;
 44     int len_n , len_m ;
 45     memset ( a, 0, sizeof (a) ) ; memset ( b, 0, sizeof (b) ) ;
 46     memset ( s, 0, sizeof (s) ) ; memset ( S, 0, sizeof (S) ) ;
 47     
 48     len_n = strlen (n) , len_m = strlen (m) ;  
 49 
 50     sqrt_int ( n, len_n ) ; for ( na = x, i = 0 ; x >= 0 ; i ++ )  a[i] = sq[x--] ;
 51     sqrt_int ( m, len_m ) ; for ( nb = x, i = 0 ; x >= 0 ; i ++ )  b[i] = sq[x--] ;
 52 
 53     for ( i = 0 ; i <= na ; i ++ )
 54     {
 55         for ( k = i, c = j = 0 ; j <= nb+1 ; j ++ , k ++ )
 56         {
 57             s[k] = (a[i] * b[j]) % 10 + c ; 
 58             c = (a[i] * b[j]) / 10 ;
 59             if (s[k] >= 10 )  { s[k] -= 10 ; c ++ ; }  
 60             S[k] += s[k] ; if ( S[k] >= 10 )  { S[k] -= 10 ; S[k+1] ++ ; }
 61         }
 62     }
 63     for ( i = MAX-1 ; i >= 0 ; i -- )  if (S[i])  break ;
 64     for ( j = i ; j >= 0 ; j -- )  printf ("%d" , S[j] ) ;
 65     putchar ('\n') ;
 66 
 67     return 0;
 68 }
 69 
 70 void sqrt_int ( char *minu_char , int len ) 
 71 {
 72     int i, j, k, m;  
 73     int s, c, flag;
 74     int first, num;
 75     memset ( minu, 0, sizeof (minu) ) ;
 76     memset ( sub, 0, sizeof (sub) ) ;
 77     memset ( sq, 0, sizeof (sq) ) ;
 78 
 79     if ( len % 2 ) 
 80     {
 81         minu[0] = minu_char[0] - '0' ;  
 82         for ( num = 3 ; num >= 0 ; num -- )  if ( minu[0] >= num*num )  break ; 
 83         sq[x=0] = num ; minu[0] -= num*num ; first = 1 ; 
 84         
 85     }
 86     else 
 87     {
 88         sq[x=0] = 0 ; first = 0 ; 
 89     }
 90 
 91     for ( i = first ; i < len ; i += 2 ) 
 92     {
 93         minu[i] = minu_char[i] - '0' ; minu[i+1] = minu_char[i+1] - '0' ;
 94         
 95         memset (sub , 0, sizeof (sub) ) ; 
 96         for ( k = 9 ; k >= 0 ; k -- ) 
 97         {
 98             sub[i+1] = k ; c = 0 ;   
 99             for ( m = i , j = x ; j >= 0 ; j -- , m -- ) 
100             {
101                 s = sq[j] * 2 ;
102                 sub[m] = s % 10 + c ;
103                 c = s / 10 ;
104             }
105             sub[m] = c ; c = 0 ;
106 
107             for ( m = i+1 ; m >= 0 ; m -- )  
108             {
109                 s = sub[m] * k ;
110                 sub[m] = s % 10 + c ;
111                 c = s / 10 ;
112                 if (sub[m] >= 10 )  { sub[m] -= 10 ; c ++ ; }
113             }
114 
115             for ( flag = m = 0 ; m <= i+1 ; m ++ )  
116             {
117                 if (minu[m] < sub[m])  { flag = 1 ; break ; }
118                 else if (minu[m] > sub[m] )  break ; 
119             }
120 
121             if ( !flag )  
122             {
123                 for ( m = i+1 ; m >= 0 ; m -- )  
124                 {
125                     if ( minu[m] < sub[m] )  { minu[m] += 10 ; minu[m-1] -- ; }
126                     minu[m] -= sub[m] ;
127                 }
128                 sq[++x] = k ; break ;
129             }
130             else  memset (sub, 0, sizeof (sub) ) ;  
131         }
132     } 
133 }

 

All Over

相關文章
相關標籤/搜索