內(nèi)容
數(shù)組
- 逆序輸出
#include<stdio.h> #define maxn 1000000 int a[maxn]; int main() { int x, n=0; // 輸入 while(scanf("%d", &x) == 1) a[n++] = x; // 輸出 for(int i=n-1; i>=1; i--){ printf("%d ", a[i]); } printf("%d\n", a[0]); return 0; }
-
a[n++]
玷或,首先賦值a[n]=x
楔脯,然后執(zhí)行n=n+1
- 對于變量n挽懦,n++和++n都會給n加1态辛,但當它們用在一個表達式中時切黔,行為有所差別:n++會使用加1的值計算表達式,而++n會使用加1后的值計算表達式
- 比較大的數(shù)組盡量聲明在main函數(shù)外监署,否則程序可能無法運行
-
- 開燈問題
n盞燈,第1個人把所有燈打開撵术,第2個人按下所有編號為2的倍數(shù)的開關(guān)(這些燈將被關(guān)掉),第3個人按下所有編號為3的倍數(shù)的開關(guān)(其中關(guān)掉的燈將被打開话瞧,開著的燈將被關(guān)掉)嫩与,依此類推。一共有k個人交排,問最后有哪些燈開著划滋?
輸入n和k,輸出開著的燈的編號埃篓。k<=n<=1000处坪。#include<stdio.h> #include<string.h> #define maxn 1010 int a[maxn]; int main() { int n, k, first = 1; // 數(shù)組a初始化為0 memset(a, 0, sizeof(a)); scanf("%d%d", &n, &k); // 模擬讓每個人去按開關(guān) for(int i=1; i<=k; i++){ for(int j=1; j<=n; j++){ if(j%i == 0){ a[j] = !a[j]; } } } // 輸出 for(int i=1; i<=n; i++){ if(a[i]){ // 輸出時第一個數(shù)字前無空格 if(first){ first = 0; }else{ printf(" "); } printf("%d", i); } } printf("\n"); return 0; }
memset(a, 0, sizeof(a));
的作用是把數(shù)組初始化為0,定義在string.h中架专。 - 蛇形填數(shù)
在nn方陣里填入1同窘,2,...胶征,nn,要求填成蛇形桨仿。n<=8睛低。
這道題的思路值得好好思考。#include<stdio.h> #include<string.h> #define maxn 20 #define maxm 20 int a[maxn][maxm]; int main() { int n, x=0, y=0, tot = 0; scanf("%d", &n); memset(a, 0, sizeof(a)); tot = a[0][y=n-1] = 1; // 賦值過程 while(tot < n*n) { // 先向下走 while(x+1<n && !a[x+1][y]) { a[++x][y] = ++tot; } // 向左走 while(y-1>=0 && !a[x][y-1]) { a[x][--y] = ++tot; } // 向上走 while(x-1>=0 && !a[x-1][y]) { a[--x][y] = ++tot; } // 向右走 while(y+1<n && !a[x][y+1]) { a[x][++y] = ++tot; } } // 輸出 for(x=0; x<n; x++) { for(y=0; y<n; y++) printf("%3d", a[x][y]); printf("\n"); } return 0; }
字符數(shù)組
- 豎式問題
模擬豎式計算服傍,但是必須豎式中所有的字符都必須屬于輸入的數(shù)字集合钱雷。#include<stdio.h> #include<string.h> int main() { int count = 0; char s[20], buf[99]; scanf("%s", s); for(int abc=111; abc<=999; abc++) { for(int de=11; de<=99; de++) { int x = abc*(de%10), y = abc*(de/10), z = abc*de; sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z); // 檢查每個字符是否都在輸入的集合 int ok = 1; for(int i=0; i<strlen(buf); i++) { if(strchr(s, buf[i]) == NULL) ok = 0; } if(ok) { printf("<%d>\n", ++count); printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n", abc, de, x, y, z); } } } printf("The number of solutions = %d\n", count); return 0; }
- 趣測試
#include<stdio.h> #include<math.h> int main() { int count = 0; printf("%d %d %d", count++, count++, count++); return 0; }
#include<stdio.h>
int main()
{
int count = 0;
count = count++;
printf("%d", count);
return 0;
}
競賽題目選講
- Tex中的引號
getchar,讀取下一個字符吹零。#include<stdio.h> int main() { int c, q=1; while((c = getchar()) != EOF) { if(c == '"') { printf("%s", q ? "``":"''"); q = !q; }else{ printf("%c", c); } } return 0; }
- WERTUYU
輸入一個錯位后敲出的字符串罩抗,輸出打字員本來想打出的句子。輸入保證合法灿椅。#include<stdio.h> char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./"; int main() { int i,c; while((c = getchar()) != EOF) { for(i=1; s[i] && s[i] != c; i++); if(s[i]){ putchar(s[i-1]); }else{ putchar(c); } } return 0; }
- 回文詞
輸入一個字符串套蒂,判斷它是否為回文串以及鏡像串钞支。輸入字符串保證不含數(shù)字0。所謂回文串操刀,就是反轉(zhuǎn)以后和原串相同烁挟,如abba和madam。所有鏡像串骨坑,就是左右·鏡像之后和原串相同撼嗓,如2S和3AIAE。注意欢唾,并不是每個字符在鏡像之后都能得到一個合法字符且警。#include<stdio.h> #include<string.h> #include<ctype.h> // 每個字符的鏡像字符 A-Z 1-9 const char* rev = "A 3 HIL JM o 2TUVWXY51SE Z 8 "; // 輸出的結(jié)果 “不是回文串” “回文串” “鏡像串” “鏡像回文串” const char* msg[] = {"not a palindrome", "a regular palindrome", "a mirrored string", "a mirrored palindrome"}; char r(char ch) { // isalpha 判斷字符是否為字母 if(isalpha(ch)) { return rev[ch - 'A']; } return rev[ch - '0' + 25]; } int main() { char s[30]; while(scanf("%s", s) == 1) { // 字符串長度 int len = strlen(s); // 標志 int p = 1, m = 1; for(int i=0; i<(len+1)/2; i++) { // 是否是回文串 if(s[i] != s[len-1-i]) { p = 0; } // 是否是鏡像串 if(r(s[i]) != s[len-1-i]) { m = 0; } } printf("%s -- is %s.\n\n", s, msg[m*2+p]); } return 0; }
- 猜數(shù)字游戲的提示
實現(xiàn)一個經(jīng)典“猜數(shù)字”游戲。給定答案序列和用戶猜的序列礁遣,統(tǒng)計有多少數(shù)字位置正確(A)斑芜,有多少數(shù)字在兩個序列都出現(xiàn)過但位置不對(B)。
這里做了一個小實驗亡脸,#include<stdio.h> #define maxn 1010 int main() { int n, a[maxn], b[maxn]; int kase = 0; while(scanf("%d", &n) == 1 && n) { printf("Game %d:\n", ++kase); // 輸入答案序列 for(int i =0 ; i<n; i++) { scanf("%d", &a[i]); } // 處理猜測序列 for(;;) { int A = 0, B = 0; // 求出位置正確的數(shù)字個數(shù)A for(int i=0; i<n; i++) { scanf("%d", &b[i]); if(a[i] == b[i]) A++; } // 當猜測序列全為0退出 int sign = 1; for(int i=0; i<n; i++){ if(b[i] != 0){ sign = 0; break; } } if(sign == 1) break; // 找到兩個序列都出現(xiàn)過的數(shù)字個數(shù)B for(int d=1; d<=9; d++) { int c1 = 0, c2 = 0; for(int i = 0; i<n; i++) { if(a[i] == d) c1++; if(b[i] == d) c2++; } if(c1<c2) B += c1; else B += c2; } // 輸出結(jié)果 printf(" (%d, %d)\n", A, B-A); } } return 0; }
#include<stdio.h> #include<math.h> int main() { int count = 0; printf("%d \n", ++count); printf("%d \n", count); return 0; }
result1
再看下面這個程序運行結(jié)果押搪,
#include<stdio.h> #include<math.h> int main() { int count = 0; printf("%d \n", count++); printf("%d \n", count); return 0; }
result2 - 生成元
如果x加上x的各個數(shù)字之和得到y(tǒng),就說x是y的生成元浅碾。給出n(1<=n<=100000)大州,
求最小生成元。無解輸出0垂谢。例如厦画,n=216, 121滥朱,2005時的解分別為198根暑,0,1979徙邻。// 一次性枚舉 #include<stdio.h> #include<string.h> #define maxn 100005 int ans[maxn]; int main() { int T, n; memset(ans, 0, sizeof(ans)); for(int m=1; m < maxn; m++){ int x = m, y = m; // 把x的每一位與x加起來 while(x > 0){ y += x % 10; x /= 10; } // 把最小的生成元保存下來 if(ans[y] == 0 || m < ans[y]){ ans[y] = m; } } scanf("%d", &T); while(T--){ scanf("%d", &n); printf("%d\n", ans[n]); } return 0; }
- 環(huán)狀序列
長度為n的環(huán)狀串有n種表示法排嫌,分別為從某個位置開始順時針得到。在這些表示法中缰犁,字典序最小的稱為“最小表示”淳地。
輸入一個長度為n(n<=100)的環(huán)狀DNA串(只包含A、C帅容、G颇象、T這4種字符)的額、一種表示法并徘,你的任務(wù)是輸出該環(huán)狀串的最小表示遣钳。#include<stdio.h> #include<string.h> #define maxn 105 // 比較分別以p和q為開頭的序列 int less(const char* s, int p, int q){ int n = strlen(s); for(int i= 0; i < n; i++){ if(s[(p+i)%n] != s[(q+i)%n]){ return s[(p+i)%n] < s[(q+i)%n]; } } return 0; } int main(){ int T; char s[maxn]; // T個字符串 scanf("%d", &T); // 獲取輸入、處理字符串 while(T--){ scanf("%s", s); // 到目前為止的標志 int ans = 0; // 字符串的長度 int n = strlen(s); // 找到最小的字符 for(int i=1; i<n; i++){ if(less(s, i, ans)) ans = i; } // 輸出最小表示 for(int i=0; i< n; i++){ putchar(s[(i+ans)%n]); } putchar('\n'); } return 0; }
練習
- 得分
給出一個由O和X組成的串(長度為1~80)麦乞,統(tǒng)計得分蕴茴。每個O的得分為目前連續(xù)出現(xiàn)的O的個數(shù)劝评,X的得分為0。#include<stdio.h> #include<string.h> char s[82]; int main() { int score=0; int sign1=0; scanf("%s", s); int strength = strlen(s); for(int i=0; i<strlen(s); i++){ if(s[i] == 'O'){ sign1++; }else{ sign1 = 0; } score += sign1; } printf("%d", score); return 0; }
- 分子量
給出一種物質(zhì)的分子式(不帶括號)荐开,求分子量付翁。本題中的分子式只包含4種原子,分別為C晃听、H百侧、O、N能扒,原子量分別為12.01佣渴,1.008,16.00初斑,14.01(單位:g/mol)辛润。例如,C6H5OH的分子量為94.108g/mol见秤。
記咨笆:字符數(shù)字轉(zhuǎn)整形數(shù)字的方法#include<stdio.h> #include<ctype.h> #include<string.h> char s[100]; // 每個字母對應(yīng)的數(shù)值 double getNum(char r){ double a = 0.0; if(r == 'C'){ a = 12.01; } if(r == 'H'){ a = 1.008; } if(r == 'O'){ a = 16.00; } if(r == 'N'){ a = 14.01; } return a; } int main(){ scanf("%s", s); double all =0; // 循環(huán)遍歷 for(int i=0; i< strlen(s); i++){ // 如果是一個字母 if(isalpha(s[i])){ // 如果不是最后一個字符 if(i+1 < strlen(s)){ // 如果下一個是數(shù)字 if(!isalpha(s[i+1])){ // 那么相乘 all += getNum(s[i])*(int)(s[i+1]-'0'); continue; }else{ // 不是數(shù)字就不用乘 all += getNum(s[i]); continue; } }else{ // 加上最后一個字符 all += getNum(s[i]); continue; } } } printf("%f\n", all); return 0; }
- 數(shù)數(shù)字
把前n(n<=10000)個整數(shù)順次寫在一起:123456789101112···數(shù)一數(shù)0~9各出現(xiàn)多少次,輸出10個整數(shù)鹃答。#include<stdio.h> #include<string.h> int a[10]; char s[100005]; int main() { scanf("%s", s); // 初始化數(shù)組 memset(a, 0, sizeof(a)); // 獲得輸入串的實際長度 int n = strlen(s); // 賦值a數(shù)組 for(int i=0; i<n; i++) { int c = (int)(s[i]-'0'); a[c]++; } // 輸出數(shù)組 for(int i=0; i<10; i++) { printf("%d ",a[i]); } return 0; }
- 周期串
如果一個字符串可以由某個長度為k的字符串重復多次得到乎澄,則稱該串以k為周期。例如测摔,abcabcabcabc以3為周期(注意置济,它也以6和12為周期)
輸入一個長度不超過80的字符串,輸出其最小周期锋八。 - 謎題
一個5*5方格浙于,其中恰好有一個格子是空的,其他格子各有一個字母挟纱。一共有4種指令:A羞酗、B、L紊服、R檀轨,分別表示把空格上、下围苫、左裤园、右的相鄰字母移到空格中撤师。輸入初始網(wǎng)格和指令序列(以數(shù)字0結(jié)束)剂府,輸出指令執(zhí)行完畢后的網(wǎng)格。如有非法指令剃盾,應(yīng)輸出“This puzzle has no final configuration.”