【第一層級 條件反射】
1、個十百千各數位的求法
q=a/1000%10;
b=a/100%10;
s=a/10%10;
g=a%10;
2、冒泡排序(以升序為例)
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
if(a[j]>a[j+1]){t=a[j]; a[j]=a[j+1]; a[j+1]=t;}
3、求素數(標簽法)
#include<stdio.h>
int
main(){
int
a,f,i;
scanf
(
"%d"
,&a);
f=1;
for
(i=2;i*i<=a;i++)
if
(a%i==0){f=0;
break
;}
if
(a==1)f=0;
if
(f==1)
printf
(
"T\n"
);
else
printf
(
"F\n"
);
return
0;
}
4、字符圖形(金字塔)
#include <stdio.h>
int
main(){
int
i,j,n;
scanf
(
"%d"
,&n);
for
(i=1;i<=n;i++){
for
(j=1;j<=n-i;j++)
printf
(
" "
);
for
(j=1;j<=i*2-1;j++)
printf
(
"*"
);
printf
(
"\n"
);
}
return
0;
}
5、閏年判斷
四年一閏,百年不閏,四百年又閏。
(y%4==0 && y%100!=0 || y%400==0)
6、各類三角形的判別
a、b、c三邊能構成三角形的條件:任意兩邊和大於第三邊
(a+b>c && b+c>a && c+a>b)
a、b、c三邊能構成直角三角形的條件:存在兩邊平方和等於第三邊平方
(a*a+b*b==c*c || b*b+c*c==a*a || c*c+a*a==b*b)
a、b、c三邊能構成銳角三角形的條件:任意兩邊平方和大於第三邊平方
(a*a+b*b>c*c && b*b+c*c>a*a && c*c+a*a>b*b)
a、b、c三邊能構成鈍角三角形的條件:存在兩邊平方和小於第三邊平方
(a*a+b*b<c*c || b*b+c*c<a*a || c*c+a*a<b*b)
7、完全數
int a[5] ={6,28,496,8128,33550336};
【第二層級 稍加思索】
1、最大公約數、最小公倍數
#include<stdio.h>
int
main(){
int
a,b,r;
scanf
(
"%d%d"
,&a,&b);
while
(b>0){
r=a%b;
a=b; b=r;
}
printf
(
"%d\n"
,a);
return
0;
}
2、篩法求素數
3、重要函數(內部函數)
數學函數
字符串函數
string s;
cin>>s; //普通輸入
getline(cin,s); //整行輸入
4、重要函數(內部函數)
(1)標簽法求素數
(2)篩法求素數
(3)輾轉相除法求GCD,LCM
【第三層級 奇思妙想】
1、快速排序
2、動態規划
3、搜索
4、高精度算法
EX01 字符圖形生成
#include<stdio.h> int main(){ int i,j,n; scanf("%d",&n); for(i=1;i<=n;i++){ for(j=1;j<=n-i;j++)putchar(' '); for(j=i;j>=2;j--)printf("%c ",j+64); puts("A"); } return 0; }
EX02數學黑洞
【題目描述】
任意一個4位自然數,將組成該數的各位數字重新排列,形成一個最大數和一個最小數,之后兩數相減,其差仍為一個自然數.重復進行上述運算,你會發現一個神秘的數.請編程把過程打印出來.
輸入
一行:一個四位數n
輸出
若干行:每行為一個減法算式
樣例輸入
1234
樣例輸出
4321-1234=3087
8730-378=8352
8532-2358=6174
7641-1467=6174
#include<stdio.h> int a[5]; int main(){ int x; scanf("%d",&x); while(x!=6174){ a[1]=x/1000%10; a[2]=x/100%10; a[3]=x/10%10; a[4]=x%10; for(int i=1;i<=3;i++) for(int j=1;j<=4-i;j++) if(a[j]>a[j+1]){int t=a[j];a[j]=a[j+1];a[j+1]=t;} int mx=a[4]*1000+a[3]*100+a[2]*10+a[1]; int mn=a[1]*1000+a[2]*100+a[3]*10+a[4]; x=mx-mn; printf("%d-%d=%d\n",mx,mn,x); } puts("7641-1467=6174"); return 0; }
EX03英雄卡
【題目描述】
小李非常迷戀收集各種干脆面里面的英雄卡,為此他曾經連續一個月都只吃干脆面這一種零食,但是有些稀有英雄卡真的是太難收集到了。后來某商場搞了一次英雄卡兌換活動,只要你有三張編號連續的英雄卡,你就可以換任意編號的英雄卡。小李想知道他最多可以換到幾張英雄卡(新換來的英雄卡不可以再次兌換)。
輸入
第一行,共一個整數n,表示小李擁有的英雄卡數。
第二行,共n個空格隔開的數字ai,表示英雄卡的編號。
輸出
輸出僅有一行,共1個整數,表示小李最多可以換到的英雄卡。
樣例輸入
6
3 1 2 4 4 5
樣例輸出
1
#include<stdio.h> #include<algorithm> using namespace std; int num[100005]; int min3(int a,int b,int c){return min(min(a,b),c);} int main(){ int a,n,i,x=0,mx=0,mn; scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&a); num[a]++; mx=max(mx,a); } for(i=1;i<=mx-2;i++){ mn=min3(num[i],num[i+1],num[i+2]); x+=mn; num[i+1]-=mn; num[i+2]-=mn; } printf("%d\n",x); return 0; } /* 20 1 4 6 8 7 3 5 5 6 3 3 5 8 9 7 6 6 7 8 10 5 */
EX04 哈夫曼編碼
【題目描述】
哈夫曼編碼是一種編碼方式,是可變字長編碼的一種,由Huffman於1952年提出。該方法完全依據字符出現概率來構造異字頭的平均長度最短的碼字,有時稱之為最佳編碼,一般就叫Huffman編碼。簡單地來說,就是出現概率高的字符使用較短的編碼,反之出現概率低的則使用較長的編碼,這便使編碼之后的字符串的平均期望長度降低,從而達到無損壓縮數據的目的。
現在請你模擬這樣的原則對給定的一個字符串進行字母統計。
輸入
只有一行,是一個字符串,由小寫英文字母組成,長度不超過255個字符。
輸出
有若干行,每行有兩部分組成:一個字母和該字母出現的頻率,中間用一個空格分隔,並按頻率高低排列,頻率相同時則按字母的ASC碼的先后順序排列。
樣例輸入
soon
樣例輸出
o 2
n 1
s 1
#include<iostream> #include<string> #include<algorithm> using namespace std; int num[30]; int main(){ string s; cin>>s; for(int i=0;i<s.size();i++)num[s[i]-'a']++; //for(int i=0;i<30;i++)cout<<num[i]<<endl; for(int k=255;k>=1;k--) for(int i=0;i<30;i++) if(num[i]==k)cout<<char(i+97)<<' '<<k<<endl; return 0; }
EX05 立方和
【題目描述】
現給出一個三位數,先對這個三位數的各位數字的立方求和,然后再對求出的和中的各位數字的立方求和,如此一直繼續下去,判斷最后能否得到一個不再變化的固定值。如能得到一個固定值,就求出這個固定值;如果不能,則輸出提示信息“error”。另外請注意,在求解過程中,若某一次求和過程中得到的值超過三位數,則取該數的低三位繼續往下運算……
例如,對於三位數111,則第一次計算應是1×1×1+1×1×1+1×1×1=3,第二次計算應是0×0×0+0×0×0+3×3×3=27,第三次計算應是0×0×0+2×2×2+7×7×7=351,第四次計算應是3×3×3+5×5×5+1×1×1=153,第五次計算應是1×1×1+5×5×5+3×3×3=153,與第四次計算的結果相同,這時可不再計算,輸出固定值153。
親愛的同學,請你也來計算一下。
輸入
只有一行,是一個三位數。
輸出
也只有一行,如能得到一個固定值,則輸出這個固定值;如不能,則輸出一個提示信息“error”。
樣例輸入
111
樣例輸出
153
輸入樣例2:
102
輸出樣例2:
error
#include<stdio.h> int main(){ int x,g,s,b,t,v[1000]; scanf("%d",&x); while(1){ t=x; //保存一遍,因為下面x會變 b=x/100%10; s=x/10%10; g=x%10; x=(b*b*b+s*s*s+g*g*g)%1000;//如超過三位按三位計算 if(x==t){printf("%d\n",x); break;}//與上一數相同剛輸出 if(v[x]==1){puts("error"); break;}//出現過這個數 v[x]=1; //這個數出現過 } return 0; }
EX06 所有數字和為M的三位數
【題目描述】
找出數字之和為M的所有三位數
輸入
一行,一個整數M,1<=M<25,不考慮無解的情況
輸出
若干行,從小到大每行一個符合條件的數
樣例輸入
20
樣例輸出
106
115
124
133
142
151
160
205
214
223
232
241
250
304
313
322
331
340
403
412
421
430
502
511
520
601
610
700
#include<stdio.h> int main(){ int i,j,k,a,m; scanf("%d",&m); for(i=1;i<=9;i++) for(j=0;j<=9;j++) for(k=0;k<=9;k++) if(i+j+k==m)printf("%d%d%d\n",i,j,k); return 0; }
EX07 所有數字和為M的三位數素數
【題目描述】
找出數字之和為M的所有三位數
輸入
一行,一個整數M,1<=M<25,不考慮無解的情況
輸出
若干行,從小到大每行一個符合條件的素數
樣例輸入
7
樣例輸出
151
223
241
313
331
421
601
#include<stdio.h> int Prime(int a){ if(a==1)return 0; for(int i=2;i*i<=a;i++) if(a%i==0)return 0; return 1; } int main(){ int i,j,k,a,m; scanf("%d",&m); for(i=1;i<=9;i++) for(j=0;j<=9;j++) for(k=0;k<=9;k++){ a=i*100+j*10+k; if(i+j+k==m && Prime(a))printf("%d\n",a); } return 0; }
EX08 棋盤格數:求正、長方形個數
【題目描述】
設有一個N*M方格的棋盤。求出該棋盤中包含有多少個正方形、多少個長方形(不包括正方形)。
例如:當N=2,M=3時:
正方形的個數有8個:即邊長為1的正方形6個;邊長為2的正方形有2個。
長方形的個數有10個:即2*1的長方形有4個;1*2的長方形有3個;3*1的長方形有2個;3*2的長方形有1個。
輸入
一行: 兩個整數N,M , 1<=N<=100,1<=M<=100
輸出
兩行:
第一行表示正方形的個數
第二行表示長方形的個數
樣例輸入
2 3
樣例輸出
8
10
提示
數長方形包括正方形的方法:(長邊上的線段數)*(寬邊上的線段數)如上例(2+1)*(3+2+1)=18個;數正方形方法:長*寬+(長-1)*(寬-1)+...+(長或寬為1),如上例2*3+1*2=8個;不包括正方形的長方形為18-8=10個。
#include<stdio.h> int main(){ int a,b,z,c,x; scanf("%d%d",&a,&b); x=((a+1)*a*(b+1)*b)/4; //四邊形個數 z=0; //正方形個數 while(a>0 && b>0){ z+=a*b; a--; b--; } printf("%d\n%d\n",z,x-z); return 0; }
EX09 王小二切餅
【題目描述】
王小二自誇刀工不錯,有人放一張大的剪餅在砧板上,問他:“餅不許離開砧板,切100刀最多能分成多少塊?”
王小二想知道切n刀最多能分成幾塊,你能幫助他嗎?
輸入
一行:一個整數n 1<=n<=100
輸出
一行:一個整數
樣例輸入
1
樣例輸出
2
提示
遞推公式:f[n]=f[n-1]+n
【代碼1】
#include<stdio.h> int main(){ int a[120],n,i; a[0]=1; for(i=1;i<=100;i++)a[i]=a[i-1]+i; scanf("%d",&n); printf("%d\n",a[n]); return 0; }
【代碼2】
#include<stdio.h> int main(){ int n; scanf("%d",&n); printf("%d\n",1+(n+1)*n/2); return 0; }
EX10 刪數
【題目描述】
輸入一個高精度的正整數N,去掉其中任意S個數字后剩下的數字按原左右次序組成一個新的正整數。編程對給定的N和S,尋找一種方案使剩下的數字組成的新數最小。
輸出去掉數字后組成的新的正整數(N不超過240位),如果高位為0,則應去掉多余的零。輸入的數據不需要判錯。
輸入
兩行:
第一行:一個不超過200位的數N
第二行:刪除和數字個數S,S<200
輸出
一行:刪除后的最小數
樣例輸入
343652
3
樣例輸出
332
提示
要在343652中刪除3個數字,使剩下的數字最小。那么,我們第一個要刪的是4,4正好處於數的下降趨勢中,第二個仍然刪除下降趨勢的6,第三個刪除5。這是一種貪心算法思想,所以本題稱之為貪心刪數。
#include<iostream> #include<string> using namespace std; int main(){ string s; int m,i; cin>>s>>m; while(m--){ for(i=0;i<s.size()-1;i++) if(s[i]>s[i+1])break; s.erase(i,1); } cout<<s<<endl; return 0; }
EX11 乘地鐵(metro)
【題目描述】
現在寧波市已經開通地鐵了,而恰好ZYH小朋友要出去玩,不喜歡擠公交的他自然也沒錢做出租車,於是地鐵是一個非常好的選擇。
地鐵的票價表可以看成一個n*n的二維表,有n行,每行n個數,第i行第j列表示從第i個站點到第j個站點的票價。現在ZYH小朋友要去m個地方,記為ai(1<=i<=m),並且他們一開始在a0號點,每次他們會從ai-1到ai,直至到達終點am。
現在ZYH小朋友想知道他需要多少錢來買地鐵票。
輸入
輸入的第一行是兩個用空格隔開的整數n(1<=n<=100),m(1<=m<=100)。
接下來是n行的票價表,每行n個整數bi,j,(0<=bi,j<=100)。
接下來的一行包含m+1個整數表示ai ,即是a0~am ,(1<=ai<=n)。
輸出
輸出一個數,表示最后需要的錢數。
樣例輸入
3 3
0 1 2
1 0 3
3 4 0
1 2 3 1
樣例輸出
7
#include<stdio.h> int a[120][120],b[120]; int main(){ int i,j,n,m,x=0; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=n;j++)scanf("%d",&a[i][j]); for(i=0;i<=m;i++)scanf("%d",&b[i]); for(i=1;i<=m;i++)x+=a[b[i-1]][b[i]]; printf("%d\n",x); return 0; }
EX12 分數線確定(line)
【題目描述】
在模擬考試結束后不久,所有考生的分數已經匯總完成,老師們開始估計某所大學的錄取分數線。分數線的划定是一個復雜的過程,但是可以根據以往錄取人數進行估計。
老師們的估計方法如下,先得到某所大學以往的錄取人數,k人。那么總分在前k名的同學都可以進入這所大學,第k名同學的分數就被作為分數線。但是考試中往往有分數相同的人,若分數線上的人有多名,那么這些同學將同時被錄取,錄取人數可能超過k人。
現在校長想要知道某所學校的分數線,以及實際可以錄取的人數。
輸入
第一行兩個整數n和k,分別表示參加考試的人數和以往錄取人數k。
接下來n行,每行1個整數,表示每位同學的總分。
輸出
一行,兩個整數,第一個是錄取分數線,第二個表示實際錄取的人數。兩個數之間用一個空格分開。
樣例輸入
6 3
721
612
603
658
598
612
樣例輸出
612 4
提示
【說明】
前3名分別為721,658,612,分數線划定為612,而612共有2人,那么一共可以錄取4人
【數據范圍】
對於50%的數據:1<=k<=n<=1000,每個人分數x的范圍0<=x<=1000.
對於100%的數據:1<=k<=n<=100000。每個人分數x的范圍0<=x<=100000000
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; int a[1000005]; bool cmp(const int& a,const int& b){return a>b;} int main(){ int n,i,k,f,r; scanf("%d%d",&n,&k); for(i=0;i<n;i++)scanf("%d",&a[i]); sort(a,a+n,cmp); f=a[k-1];r=k; for(i=k;i<n;i++)if(a[i]==f)r++; printf("%d %d\n",f,r); return 0; }
EX13 最大公約數與最小公倍數
【題目描述】
兩個正整數的最大公約數是G,最小公倍數是L,它們的和最小是多少?
輸入
兩個不大於10000的正整數G和L,中間用單個空格隔開。數據保證L是G的倍數。
輸出
一個正整數,即最小的和。
樣例輸入
14 280
樣例輸出
126
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; int main(){ int G,L,c; scanf("%d %d",&G,&L);c=L/G; for(int i=(int)sqrt(c);i>=1;i--) if(c%i==0 && __gcd(i,c/i)==1){ printf("%d\n",G*(i+c/i)); return 0; } }
EX14 彩票中獎 (lottery.pas/c/cpp)
【題目描述】
小明想試試運氣去購買彩票,所以他開始研究彩票大樂透的玩法:
超級大樂透是指由購買者從01—35共35個號碼中選取5個號碼為前區號碼,並從01—12共12個號碼中選取2個號碼為后區號碼組合為一注彩票進行的投注。每注金額人民幣2元。小明打算用自己的零花錢去試試運氣,選擇了一組心目中的幸運數字,買了一張彩票。如下圖:
兩天后,中獎號碼公布,小明開始研究到底中了多少獎金。獲獎方式如上右圖:例如,中4+2就表示前區有4個數字相同,后區2個數字相同,獲得三等獎,獎金3000元。
對照中獎號碼對小明來說是一個頭疼的問題,他找到你,希望你幫忙寫一個程序,只要輸入彩票號碼和開獎號碼,就可以知道獎金值。
輸入
第一行7個整數,表示小明購買的彩票號碼。前5個為前區號碼,范圍在1到35,保證不會重復;后2個為后區號碼,范圍在1到12,保證不重復。
第二行7個整數,表示開獎號碼,前5個為前區中獎號碼,范圍在1到35,保證不重復且保證有序;后2個為后區號碼,范圍在1到12,保證不重復且有序。
注意,前區和后區是分開選數的,前區的數字可以和后區的數字相同。
輸出
輸出小明的中獎金額,未中獎輸出0。
樣例輸入
2 7 8 14 18 6 11
2 7 8 14 18 6 11
樣例輸出
5000000
提示
【樣例1解釋】
前5加后2都相同,中一等獎,獎金為500萬。
【輸入輸出樣例2】
lottery.in
2 7 8 14 18 6 11
1 11 14 18 25 6 11
lottery.out
10
【樣例2解釋】
前區有14和18兩個數字相同,后區6和11都相同,對照表格,中獎2+2為五等獎,獎金10元。
【數據范圍】
對於40%的數據,若小明的號碼與中獎號碼相同,那么其位置也是相同的。例如中獎號碼10位於第三個數,那么小明的彩票中如果出現10,也肯定在第三個數。
對於前70%的數據,小明的號碼是系統產生的,前區和后區都是從小到大給出的。
對於最后30%的數據,小明的號碼可能是手寫的,前區或后區的數字不一定有序。
#include<stdio.h> int x[10],y[10],t[10][10]; int main(){ int a,b,i,j,u=0,v=0; t[5][2]=5000000; t[5][1]=250000; t[5][0]=t[4][2]=3000; t[4][1]=t[3][2]=200; t[4][0]=t[3][1]=t[2][2]=10; t[3][0]=t[1][2]=t[2][1]=t[0][2]=5; for(i=1;i<=7;i++)scanf("%d",&x[i]); for(i=1;i<=7;i++)scanf("%d",&y[i]); for(i=1;i<=5;i++) for(j=1;j<=5;j++) if(x[i]==y[j])u++; for(i=6;i<=7;i++) for(j=6;j<=7;j++) if(x[i]==y[j])v++; printf("%d\n",t[u][v]); return 0; }
EX15 足球聯賽
【題目描述】
在足球比賽中,各國主要以聯賽方式進行:
聯賽中,每個隊伍都會兩兩進行主客場交手,獲得勝利的隊伍全取3分;失利的隊伍不得分;若雙方戰平,則各得1分。而統計球隊的積分,則難壞了小明,他想要請你開發一個軟件,幫他統計一下整個賽季結束之后各個球隊的積分情況,以便向外界公布。
輸入
第一行一個整數N,表示共有N個球隊。2<=N<=50.
接下來N行,表示每個球隊在主場作戰的情況。每行共N個元素,“W”表示主隊獲勝,“D”表示雙方戰平,“L”表示主隊失利。自己和自己用“-”表示。
輸出
共1行: N個數,表示N個球隊的積分情況,中間用空格分隔,最后一個球隊后不要有空格。
樣例輸入1
3
-WW
W-W
WW-
樣例輸出
6 6 6
提示
輸入樣例2
3
-DD
L-L
WD-
輸出樣例2:
5 2 8
第一個球隊,主場2平,客場一勝一負,共積5分。第二個球隊主場全負,客場兩平,積2分。第三個球隊主場一勝一平,客場一勝一平,積8分。
#include<iostream> using namespace std; int x[60]; int main(){ int i,j,n; char c; cin>>n; for(i=1;i<=n;i++) for(j=1;j<=n;j++){ cin>>c; if(c=='W')x[i]+=3; if(c=='L')x[j]+=3; if(c=='D'){x[i]++;x[j]++;} } for(i=1;i<=n-1;i++)cout<<x[i]<<' '; cout<<x[n]<<endl; return 0; }
EX16 jz1286【基礎】小冬冬歷險記
【題目描述】
小冬冬歷險記:小冬冬來到一條河邊,河中有排成一直線的幾個石墩,每個石墩上面有一枚金幣,小冬冬為了湊一些盤纏,決定跳到這些石墩上拿這些金幣,讀入小冬冬一次跳躍的最大距離和每個石墩離開岸邊的距離(不考慮石墩本身的大小,只要一次跳躍的最大距離大於等於石墩的間隔距離就算可以到達),問最多能拿到幾枚金幣。如下示意圖:
輸入
第一行:一個整數x,即一次跳躍的最大距離(1≤x≤30)第二行:石墩的個數n(0≤n≤20)第三行:n個整數,用空格隔開,表示每個石墩離開河岸的距離ai(0<ai≤500)
輸出
一個整數,即可以拿到的最多金幣數
樣例輸入
5
6
4 8 13 20 25 26
樣例輸出
3
#include<cstdio> #include<algorithm> using namespace std; int a[30]; int main(){ int i,n,k,x=0; scanf("%d%d",&k,&n); for(i=1;i<=n;i++)scanf("%d",&a[i]); sort(a+1,a+n+1); for(i=1;i<=n;i++) if(a[i]-a[i-1]<=k)x++; else break; printf("%d\n",x); return 0; }
EX17 jz1066 【入門】一年中的第幾天
【題目描述】
給定一個具體的日期,請輸出,這一天是當年的第幾天?
輸入
輸入一行,為年-月-日,
輸出
輸出一行,只有一個整數,表示這一天為那一年的第多少天
樣例輸入
2000-1-31
樣例輸出
31
#include<stdio.h> int a[12]={0,31,28,31,30,31,30,31,31,30,31,30}; int main(){ int y,m,d,x=0; scanf("%d-%d-%d",&y,&m,&d); for(int i=1;i<=m-1;i++)x+=a[i]; x+=d; if((y%4==0 && y%100!=0 || y %400==0)&& m>2)x++; printf("%d\n",x); return 0; }