算法竞赛入门经典第四章

例题4-3 救济金发放 UVa133

#include <stdio.h>
#include <stdlib.h>

#define maxn 25

int n,k,m,a[maxn];
int go(int p,int d,int t){
	while(t--){
		do{
			p=(p+d+n-1)%n+1;
		}while(a[p]==0);
	}
	return p;
}
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[]) {
	while(scanf("%d%d%d",&n,&k,&m)==3&&n){
		int i;
		for(i=1;i<=n;i++)
		    a[i]=i;
		int left=n;
		int p1=n,p2=1;
		while(left){
			p1=go(p1,1,k);
			p2=go(p2,-1,m);
			printf("%3d",p1);left--;
			if(p2!=p1){
				printf("%3d",p2);left--;
			}
			a[p1]=a[p2]=0;
			if(left)
			    printf(","); 
		}
		printf("\n");
	} 
	return 0;
}

例题4-4 信息解码 UVa213

开始头秃

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int code[8][1<<8];

int readcodes(){                        //读编码头 
	int len,i;
	memset(code,0,sizeof(code));
	for(len=1;len<8;len++){
		for(i=0;i<(1<<len)-1;i++){
			int ch=getchar();
			if(ch==EOF)
			    return 0;
			if(ch=='\n'||ch=='\r')
			    return 1;
			code[len][i]=ch;
		}
	}
	return 1;
}
int readchar(){
	while(1){
		int ch=getchar();
		if(ch!='\n'&&ch!='\r')
		    return ch;
	}
}
int readint(int c){
	int v=0;
	while(c--)
	    v=v*2+readchar()-'0';           //将二进制的编码转换为十进制 
	    return v;
}
 
int main(int argc, char *argv[]) {
	while(readcodes()){
		for(;;){
			int len=readint(3);         //读编码长度
			if(len==0)                  //v=全0,编码结束 
			    break;
			for(;;){
				int v=readint(len);
				if(v==(1<<len)-1)       //v=全1,小节结束 
				    break;
				putchar(code[len][v]);
			}
		}
		putchar('\n');
	}
	return 0;
}

习题4-2 正方形 UVa201


样例输入输出是这样的,巴特大概是我没懂题意吗??

4行4列为什么会有(V 4 1)??我理解的(V 4 1)是从第四行第一列到第五行第一列的线段即(4,1)-(5,1)

我的输入输出是这样的。。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define maxn 10

int H[maxn][maxn],V[maxn][maxn];
int count[maxn];

int is_square(int i,int j,int k){
	int m,flag;
	flag=1;
	for(m=0;m<k;m++){
		if(!(H[i][j+m]&&H[i+k][j+m]&&V[i+m][j]&&V[i+m][j+k])){
			flag=0;
			break;
		}
	}
	return flag;
}

int main(int argc, char *argv[]) {
	//int n;
	int n,m;
	char s[2];
	int i,j;
	int k;
	int T=0;
	while(scanf("%d",&n)!=EOF&&n){
		int no_square=1;
		T++;
		scanf("%d",&m);
		memset(H,0,sizeof(H));
		memset(V,0,sizeof(V));
		memset(count,0,sizeof(count));
		while(m--){
			scanf("%s%d%d",&s,&i,&j);
			//printf("%c %d %d\n",s[0],i,j);
			if(s[0]=='H')
			    H[i][j]=1;
			else if(s[0]=='V')
			    V[i][j]=1;
		}
		
		for(k=1;k<=n-1;k++){
			for(i=1;i<=n-k;i++){
				for(j=1;j<=n-k;j++){
					count[k]+=is_square(i,j,k);
				}
			}
		}
		if(T>1)
		    printf("\n**********************************\n\n");
		printf("Problem #%d\n\n",T);
		for(i=0;i<maxn;i++){
			if(count[i]){
			    printf("%d square (s) of size %d\n",count[i],i);
			    no_square=0;
			}
		}
		if(no_square==1)
		    printf("No completed squares can be found.\n");
		
	} 
	return 0;
}

*************习题4-3 黑白棋 UVa220


习题4-4 骰子涂色 UVa253


16,25,34是相对的面。123是相邻面。分别比较两个骰子各对立面和相邻面是否相同

(这个代码emmmm一眼难尽,好好反省一下为啥写这么啰嗦)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef struct{
	char x,y;
}duilimian;
typedef struct{
	duilimian a[3];
}zft;

int main(int argc, char *argv[]) {
	char s[15];
	zft r0,r1;
	int i,j;
	int flag=1;
	while(scanf("%s",s)){
		for(i=0;i<3;i++){
			if(s[i]<=s[5-i]){
				r0.a[i].x=s[i];
				r0.a[i].y=s[5-i];
			}
			else{
				r0.a[i].x=s[5-i];
				r0.a[i].y=s[i];
			}
			//printf("%c %c\n",r0.a[i].x,r0.a[i].y);
		}
		for(i=6;i<9;i++){
			if(s[i]<=s[17-i]){
				r1.a[i-6].x=s[i];
				r1.a[i-6].y=s[17-i];
			}
			else{
				r1.a[i-6].x=s[17-i];
				r1.a[i-6].y=s[i];
			}
			//printf("%c %c\n",r1.a[i-6].x,r1.a[i-6].y);
		}
		for(i=0;i<3;i++){
			for(j=0;j<3;j++){
				if(r0.a[i].x==r1.a[j].x&&r0.a[i].y==r1.a[j].y){
					r1.a[j].x=0;
					r1.a[j].y=0;
					break;
				}   
			}
		}
		for(i=0;i<3;i++){
			if(r1.a[i].x!=0){
			    printf("FALSE\n");
			    flag=0;
			    break;
			}
		}
		if(flag==1)
		    printf("TRUE\n");
	}
	return 0;
}

习题4-5 IP网络 UVa1590

IP地址转换为二进制形式,从最高位开始逐位比较,不同时从该位置开始往后都写0,就是最小网络地址

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

/*
3
194.85.160.177
194.85.160.183
194.85.160.178
*/

int main(int argc, char *argv[]) {
	while(1){
	    int n,num=0;
	    int i,j;
	    int flag,flag1;
	    char s[20][17];
	    int t[20][4],r[20][8];
	    int a;
	    int code,address;
		scanf("%d",&n);
		for(i=0;i<n;i++){
			scanf("%s",s[i]);
			num=0;
			int k=0;
			for(j=0;j<17;j++){
				if(s[i][j]=='.'||s[i][j]=='\0'||s[i][j]=='\r'){
					t[i][k]=num;
					k++;
					num=0;
					continue;
				}
				num=num*10+s[i][j]-'0';
			}
		}
		flag=0;
		for(j=0;j<4;j++){
			a=t[0][j];
			for(i=0;i<n;i++){
				if(t[i][j]!=a){
					flag=j;
					break;
				}
			}
			if(flag!=0)
			    break;
		}
		
		for(i=0;i<n;i++){
			a=t[i][flag];
			for(j=7;j>=0;j--){
			    r[i][j]=a%2;
			    a=a/2;
			}
			//j=7;
		}
		flag1=0;
		for(j=0;j<8;j++){
			a=r[0][j];
			for(i=0;i<n;i++){
				if(r[i][j]!=a){
					flag1=j;
					break;
				}
			}
			if(flag1!=0)
			    break;
		}
		
		code=0;
		address=0;
		for(i=0;i<8;i++){
			if(i<flag1){
			    address=address*2+r[1][i];
			    code=code*2+1;
			}
			else{
			    address=address*2;
			    code=code*2;
			}
		}
		for(i=0;i<4;i++){
			if(i<flag)
				printf("%d",t[1][i]);
			else if(i=flag)
			    printf("%d",address);
			else if(i>flag)
			    printf("0");
			if(i<3)
			    printf(".");
		}
		printf("\n");
		for(i=0;i<4;i++){
			if(i<flag)
				printf("255");
			else if(i=flag)
			    printf("%d",code);
			else if(i>flag)
			    printf("0");
			if(i<3)
			    printf(".");
		}
		printf("\n");
	}
	return 0;
}

习题4-6  莫尔斯电码 UVa508


习题4-7 RAID技术 UVa509



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值