開燈問題(P39)
n盞燈,編號為1-n匠璧,第一個人把所有燈打開,第二個人按下編號為2的倍數(shù)的燈的開關(guān)咸这,第三個人按下編號為3的倍數(shù)的燈的開關(guān)夷恍,以此類推,一共有k個人炊苫,問最后有哪些燈開著裁厅。
// 3開燈問題.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
int n,k;
int a[1005];
int first = 0;
while(scanf("%d%d",&n,&k)){
memset(a,0,sizeof(a));
for(int i=1;i<=k;i++){
for(int j=1;j<=n;j++){
if(j%i==0)a[j] = !a[j];
}
}
for(i=1;i<=n;i++){
if(a[i]){
if(first==0){printf("%d",i);first=1;}
else printf(" %d",i);
}
}
printf("\n");
}
return 0;
}
蛇形填數(shù)(P39)
在n*n的方陣?yán)锾钊?,2,3...,n*n侨艾,要求填成蛇形执虹。例如,n=4時的方陣為:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
先判斷唠梨,再填數(shù)袋励。這個題必須得建立二維數(shù)組才輸出成這樣,所以不要猶豫当叭。
// 3蛇形填數(shù).cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
int n;
int a[10][10];
while(scanf("%d",&n)){
memset(a,0,sizeof(a));
int tot = 0;
int x = 0;
int y = n-1;
a[x][y] = ++tot;
while(tot<n*n){
while(x+1 <= n-1 && a[x+1][y] == 0) a[++x][y] = ++tot;
while(y-1 >= 0 && a[x][y-1] == 0) a[x][--y] = ++tot;
while(x-1 >= 0 && a[x-1][y] == 0) a[--x][y] = ++tot;
while(y+1 <= n-1 && a[x][y+1] == 0) a[x][++y] = ++tot;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%3d",a[i][j]);
}
printf("\n");
}
}
return 0;
}
豎式問題(P41)
最開始無從下手茬故,但其實已經(jīng)遇到很多這樣的循環(huán)枚舉的題目了,就從題意開始蚁鳖,枚舉三位數(shù)和兩位數(shù)磺芭。
strchr(a,'b')
是在字符串a(chǎn)中查找b字符,如果找不到就返回NULL醉箕,strlen
返回字符串真實長度钾腺。
// 3豎式問題.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
char num[11];
while(scanf("%s",num)){
int count = 1;
for(int i=100;i<1000;i++){
for(int j=10;j<100;j++){
int ok = 1;
int abc = i;
int de = j;
int temp1 = abc * (de%10);
int temp2 = abc * (de/10);
int temp3 = abc * de;
char buf[50];
sprintf(buf,"%d%d%d%d%d",abc,de,temp1,temp2,temp3);
for(int q=0;q<strlen(buf);q++){
if(strchr(num,buf[q])==NULL) ok = 0;
}
if(ok){
printf("<%d>\n",count++);
printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n",abc,de,temp1,temp2,temp3);
}
}
}
printf("\nThe number of solutions = %d\n",--count);
}
return 0;
}
例題3-1 TeX中的引號(UVa272)(P45)
這個題主要就是知道了
int c;
c = getchar();
是正確的
char c;
c = getchar();
是錯誤的,因為getchar的返回值是int型讥裤。
EOF表示End Of File放棒,表示輸入流的結(jié)尾,其代表的是-1己英,用char類型來表示負數(shù)是錯誤的间螟,所以是int。
scanf("%s",s)在讀取字符串的時候损肛,遇到空格厢破,Tab,換行都會停止讀取治拿。
例題3-2 WERTYU(UVa10082)(P47)
鍵盤輸入右錯一位摩泪,輸入一個錯位后的字符串,均大寫忍啤,輸出錯位修正后的字符串加勤。
// lt32.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
int c;
while((c=getchar())!=EOF){
for(int i=0;i<strlen(s);i++){
if(s[i] == c){putchar(s[i-1]);break;}
}
if(i == strlen(s))putchar(c);
}
printf("\n");
return 0;
}
3-3回文詞(UVa401)
判斷一個字符串是否是回文串,以及鏡像串
// lt33.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char mirror[] = "A 3 HIL JM O 2TUVWXY51SE Z 8 ";
char fun(char c){
if(isalpha(c))return mirror[c-'A'];
else return mirror[c-'0'+25];
}
int main(int argc, char* argv[])
{
char input[30];
char* msg[] = {"is not a palindrome","is a regular palindrome","is a mirrored string","is a mirrored palindrome"};
char ch[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
while(scanf("%s",input)){
int p=1,m=1;
for(int i=0;i<(strlen(input)+1)/2;i++){
//這塊不能判斷相等然后賦值為1同波,邏輯會出現(xiàn)錯誤
if(input[i] != input[strlen(input)-1-i]) p=0;
if(fun(input[i]) != input[strlen(input)-1-i]) m=0;
}
/*
printf("%s -- ",input);
if(m+p==0)printf("%s.\n",msg[0]);
if(m+p==1){
if(m==1) printf("%s.\n",msg[2]);
else printf("%s.\n",msg[1]);
}
if(m+p==2)printf("%s.\n",msg[3]);
*/
printf("%s -- %s.\n.\n",input,msg[2*m+p]);
}
return 0;
}
例題3-4猜數(shù)字游戲的提示(UVa 340)
給定答案序列和用戶猜的序列鳄梅,統(tǒng)計有多少數(shù)字位置正確(A),有多少數(shù)字在兩個序列都出現(xiàn)但位置不對(B)
又是一個枚舉循環(huán)未檩,對于每個數(shù)字統(tǒng)計兩個序列中數(shù)字出現(xiàn)的次數(shù)戴尸,兩個次數(shù)取最小值,注意時每個數(shù)字都要取最小值然后累加到B上冤狡,最后B減A孙蒙。
// lt34.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#define min(a,b) a>b?b:a
int main(int argc, char* argv[])
{
int count;
int num = 1;
while(scanf("%d",&count)&&count){
printf("Game %d:\n",num++);
int a[1005],s[1005];
for(int i=0;i<count;i++){
scanf("%d",s+i);
}
while(1){
int sum=0;
int A=0,B=0;
for(int i=0;i<count;i++){
scanf("%d",a+i);
sum += a[i];
}
if(sum == 0)break;
for(i=0;i<count;i++){
if(a[i] == s[i]) A++;
}
for(i=1;i<=9;i++){
int b1=0,b2=0;
for(int j=0;j<count;j++){
if(a[j] == i)b1++;
if(s[j] == i)b2++;
}
B += min(b1,b2);
}
printf("(%d,%d)\n",A,B-A);
}
}
return 0;
}
例題3-5 生成元(UVa1583)(P52)
如果x加上x的各個數(shù)字之和得到y(tǒng),就說x是y的生成元悲雳。給出n(1<=n<=100000)挎峦,求最小生成元,無解輸出零合瓢。
第一次做查表的題目坦胶。遇到一個數(shù)就枚舉的話,效率并不高晴楔,因為很明顯每個數(shù)只會對應(yīng)一個固定的結(jié)果顿苇,所以完全可以把這些結(jié)果都提前計算好,并存儲起來税弃,輸出結(jié)果就直接查表纪岁。
// lt35.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
int ans[100005];
memset(ans,0,sizeof(ans));
for(int i=1;i<=100000;i++){
int x=i,y=i;
while(x>0){
y += x%10;
x = x/10;
}
if(ans[y] == 0 || i < ans[y]) ans[y] = i;
}
int count;
int n;
scanf("%d",&count);
while(count--){
scanf("%d",&n);
printf("%d\n",ans[n]);
}
return 0;
}
例題3-6 環(huán)狀序列(UVa1584)
最近在網(wǎng)上提交這道題,至少還是參加過比賽的则果,完全忘記了提交注意事項幔翰。
1.因為是用VC寫的,
#include "stdafx.h"
會有這么一個頭短条,在提交時不要加上导匣。
2.我覺得VC違背了c語言的塊級作用域,如圖使用會報重復(fù)定義的錯茸时。但不應(yīng)該報錯的贡定,應(yīng)該使用其他IDE不會出現(xiàn)這種情況,不得已提出i
的定義可都,放在最開始缓待。點這個網(wǎng)友回答蠻好的
一句話夠了,取余來實現(xiàn)循環(huán)渠牲。
// lt36.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
int less(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 argc, char* argv[])
{
int count;
scanf("%d",&count);
char s[105];
while(count--){
int ans = 0;
int i;
scanf("%s",s);
for(int i=0;i<strlen(s);i++){
if(less(s,i,ans)) ans = i;
}
for(int i=0;i<strlen(s);i++){
putchar(s[(ans+i)%strlen(s)]);
}
printf("\n");
}
return 0;
}
習(xí)題3-1 得分(UVa1585)
簡單題
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
int T;
scanf("%d",&T);
while(T--){
char s[85];
scanf("%s",s);
int tot = 0,sum =0;
for(int i=0;i<strlen(s);i++){
if(s[i] == 'O') {tot++;sum+=tot;}
else tot = 0;
}
printf("%d\n",sum);
}
return 0;
}
習(xí)題3-2 分子量(UVa1586)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int fun(int A,char *str,int i){
if(isdigit(str[i+1])){
if(isdigit(str[i+2])){
A += str[i+2] - '0';
A += (str[i+1] - '0')*10;
}
else
A += str[i+1] - '0';
}
else A++;
return A;
}
int main(int argc, char* argv[])
{
float ch[] = {12.01,1.008,16.00,14.01};
int T;
scanf("%d",&T);
while(T--){
char str[85];
int C=0,H=0,O=0,N=0;
scanf("%s",str);
for(int i=0;i<strlen(str);i++){
if(str[i] == 'C'){
C = fun(C,str,i);
}
else if(str[i] == 'H'){
H = fun(H,str,i);
}
else if(str[i] == 'O'){
O = fun(O,str,i);
}
else if(str[i] == 'N'){
N = fun(N,str,i);
}
}
float sum = ch[0]*C+ch[1]*H+ch[2]*O+ch[3]*N;
printf("%.3f\n",sum);
}
return 0;
}
這個使用傳址實現(xiàn)旋炒,比較方便,最開始*A
沒有加括號签杈,導(dǎo)致程序出現(xiàn)錯誤瘫镇,所以一定要記得指針在運算時一定要加括號鼎兽。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void fun(int *A,char *str,int i){
if(isdigit(str[i+1])){
if(isdigit(str[i+2])){
(*A) += str[i+2] - '0';
(*A) += (str[i+1] - '0')*10;
}
else
(*A) += str[i+1] - '0';
}
else (*A)++;
}
int main(int argc, char* argv[])
{
float ch[] = {12.01,1.008,16.00,14.01};
int T;
scanf("%d",&T);
while(T--){
char str[85];
int C=0,H=0,O=0,N=0;
scanf("%s",str);
for(int i=0;i<strlen(str);i++){
if(str[i] == 'C'){
fun(&C,str,i);
}
else if(str[i] == 'H'){
fun(&H,str,i);
}
else if(str[i] == 'O'){
fun(&O,str,i);
}
else if(str[i] == 'N'){
fun(&N,str,i);
}
}
float sum = ch[0]*C+ch[1]*H+ch[2]*O+ch[3]*N;
printf("%.3f\n",sum);
}
return 0;
}
習(xí)題3-3 數(shù)數(shù)字UVa1225
#include <stdio.h>
#include <string.h>
char s[100000];
int main(int argc, char* argv[])
{
int T;
scanf("%d",&T);
while(T--){
int q[10];
memset(q,0,sizeof(q));
memset(s,'\0',sizeof(s));
int num,i;
scanf("%d",&num);
for(i=1;i<=num;i++){
char buf[10];
sprintf(buf,"%d",i);
strcat(s,buf);
}
for(i=0;i<strlen(s);i++){
q[s[i]-'0']++;
}
for(i=0;i<9;i++){
printf("%d ",q[i]);
}
printf("%d\n",q[9]);
}
return 0;
}
習(xí)題3-4 周期串UVa455
像這種類似循環(huán)的題目,跟取余一定有關(guān)系铣除。原題里的空行我一直沒讀懂谚咬,尷尬英語不好。
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
int T;
scanf("%d",&T);
while(T--){
char str[85];
scanf("%s",str);
int length = strlen(str);
for(int i=1;i<=length;i++){
if(length%i == 0){
int j;
for(j=0;j<length;j++){
if(str[j] != str[j%i]) break;
}
if(j == length){
printf("%d\n",i);
break;
}
}
}
if (T) printf("\n");
}
return 0;
}
習(xí)題3-5 謎題UVa227
首先解決的是二維數(shù)組的輸入尚粘,考慮到會有空格在輸入里择卦,剛開始嘗試的是getchar實現(xiàn),但是要循環(huán)讀入時郎嫁,要控制換行\(zhòng)n的讀入秉继,存儲空格的位置。而且這個題目有坑泽铛,就在題目中賦值的測試數(shù)據(jù)尚辑,如果空格在最右邊的話,拖拽復(fù)制的話根本沒有復(fù)制到空格盔腔,放在控制臺直接驗證會出錯腌巾,但依據(jù)題意來說,其實是有空格的铲觉。
紫書上說gets函數(shù)已經(jīng)被廢棄了澈蝙,但是從這道題發(fā)現(xiàn)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char* argv[])
{
int count=1;
bool line = false;
while(1){
char init[5][5];
char c;
int puzzle=1;
int i,j;
int bi,bj;
gets(init[0]);
if(init[0][0] == 'Z')return 0;
for(i=1;i<5;i++){
gets(init[i]);
}
for(i=0;i<5;i++){
for(j=0;j<5;j++){
c = init[i][j];
if(c == ' ') {
bi = i;bj = j;
i = 5;j=5;
}
}
}
char command [1000];
bool valid = true;
bool exit_koro = false;
while ( !exit_koro && gets (command)) {
for ( int i = 0; command [i] != 0; i++ ) {
if ( command [i] == '0' || !valid ) {
exit_koro = true;
break;
}
switch (command [i]) {
case 'A' :
if ( bi == 0 )
valid = false;
else {
init [bi] [bj] = init [bi - 1] [bj];
init [bi - 1] [bj] = ' ';
bi--;
}
break;
case 'B' :
if ( bi == 4 )
valid = false;
else {
init [bi] [bj] = init [bi + 1] [bj];
init [bi + 1] [bj] = ' ';
bi++;
}
break;
case 'R' :
if ( bj == 4 )
valid = false;
else {
init [bi] [bj] = init [bi] [bj + 1];
init [bi] [bj + 1] = ' ';
bj++;
}
break;
case 'L' :
if ( bj == 0 )
valid = false;
else {
init [bi] [bj] = init [bi] [bj - 1];
init [bi] [bj - 1] = ' ';
bj--;
}
break;
}
}
}
if ( line )
printf ("\n");
line = true;
printf ("Puzzle #%d:\n", count++);
if ( valid ) {
for ( int i = 0; i < 5; i++ ) {
printf ("%c %c %c %c %c\n", init [i] [0], init [i] [1],
init [i] [2], init [i] [3], init [i] [4]);
}
}
else
printf ("This puzzle has no final configuration.\n");
}
return 0;
}