• 例题4-1-3-古老的密码、刽子手的游戏,救济金发放


    例题4-1 古老的密码

    • 因为字母可以重排,所以顺序不重要,而又同时因为可以映射,所以字母具体是什么不重要==>只要统计排序后的结果相同就行了
    • RE(Runtime error)错法加一: 题号提交错误
    #include <stdio.h>
    #include <string.h>
    
    void Bubblesort(int *cnt)//冒泡排序,从大到小顺序
    {
        int i,j;
        int min=cnt[0];
        for (i = 0; i <26; ++i)
        {
           for ( j = i+1; j < 26; ++j)
           {
               if (cnt[i] < cnt[j])
               {
                   min = cnt[i];
                   cnt[i]=cnt[j];
                   cnt[j] = min;
               }
           }
        }
    }
    
    int main()
    {
        char s[2][105];	//存放猜测字符串的
        int cnt[2][27]; //存放字母出现次数
        int nlen[2];	//字符串的长度
        while(scanf("%s%s",s[0],s[1])!= EOF)
        {
            memset(cnt,0,sizeof(cnt));
            int i;
            for ( i = 0; i < 2; ++i)
            {
                nlen[i]= strlen(s[i]);
                int j;
                for ( j = 0; j < nlen[i]; ++j)
                    cnt[i][s[i][j]-'A'] ++;
                Bubblesort(cnt[i]);
            }
            
            int k;
            for ( k = 0; k < 26; ++k)
            {
                if (cnt[0][k] != cnt[1][k])
                {
                    printf("NO
    ");
                    break;
                }
            }
            if (k==26) printf("YES
    " );	//如果26个字母出现次数比完全相等,则可以说相同.
        }
        return 0;
    }
    

    例题4-2 刽子手的游戏

    • 注意全局变量是否使用的问题,全局变量尽量少用...但维护内容较多的情况下,可以考虑
    • 采用"自顶向下"的顺序
    #include <stdio.h>
    #include <string.h>
    #define maxn 100
    char ans[maxn],gue[maxn];
    int left,chance;
    int win,lose;
    void guess(char ch)
    {
    	int bad=1;
    	int i;
    	for ( i = 0; i < strlen(ans); ++i)		//判断ch字母是否在字符串中
    	{
    		if (ans[i]==ch)
    		{
    			ans[i] = ' ';
    			bad =0;
    			left--;							//如果在的话,还剩未猜中字母数-1,机会不变
    		}
    	}
        	if (bad) chance--;					//如果不在的话机会-1
    		if(!chance) lose=1;
    		if(!left) win=1;
    }
    
    int main()
    {
    	int rnd;
    	while(scanf("%d%s%s",&rnd,ans,gue)==3 && rnd !=-1)
    	{
    		printf("Round %d
    ",rnd);
    		win = lose =0;
    		left= strlen(ans);
    		chance = 7;
    		int i;
    		int anslen=strlen(gue);
    		for( i=0;i< anslen;i++) { guess(gue[i]); if(win || lose) break;}
    			if(win) printf("You win.
    ");
    			else if(lose) printf("You lose.
    ");
    			else printf("You chickened out.
    ");
    	}
    	return 0;
    }
    
    #include <stdio.h>
    #include <string.h>
    
    char a[1000],g[1000];//储存字符串 
    int abook[26],gbook[26];//标记26个字母出现频率 
    int main(){
        int k;
        int alen,glen;
        int i;
        int j;
        int suc,fau;
        int acount;
        while(scanf("%d",&k)==1&&k!=-1){
            scanf("%s%s",a,g);
            memset(abook,0,sizeof(abook));
            memset(gbook,0,sizeof(gbook));
            alen=strlen(a);
            glen=strlen(g);
            for(i=0;i<alen;i++)//统计答案字母频率 
                abook[a[i]-'a']++;
            
            acount=0;
            for(i=0;i<26;i++)
                if(abook[i])//统计答案的字母组成个数(扣除雷同字母) 
                    acount++;
            
            suc=0;//猜对次数
            fau=0;//猜错次数
            for(i=0;i<glen;i++){//以猜测字母为基准进行扫描 
                j=g[i]-'a';
                if(abook[j]==0){//答案无此字母,猜测错误 
                    fau++;
                    if(fau==7)//彻底失败 
                        break;
                }else if(abook[j]!=0){//猜中字母 
                    suc++;
                    abook[j]=0;//将此字母从答案中剔除出去,此句比较关键!(再猜无效) 
                    if(suc==acount)//成功 
                        break;
                }
            }
            
            printf("Round %d
    ",k);
            if(fau>=7)//猜错7次及以上 
                printf("You lose.
    ");
            else if(suc==acount)//全部猜对 
                printf("You win.
    ");
            else
                printf("You chickened out.
    ");   
        }
        return 0;
    }
    

    例题4-3 救济金发放

    • 圆圈如何轮回==>本质上是要求,大于n变成1,小于1变成n...实现1.越界后归正。2.(xxx)%n,
    • 领过设为1,没领过(初始)设为1
    较为简洁、清晰的做法
    #include <stdio.h>
    #include <string.h>
    
    int book[100];//领过的标记1,没领过的标记0 
    int main(){
        int n,k,m;
        int kcount,mcount;
        int ki,mi;
        int kout,mout;
        int first;
        int ncount;
        while(scanf("%d%d%d",&n,&k,&m)==3&&n&&k&&m){
            memset(book,0,sizeof(book));
            ncount=0;
            
            ki=0;
            mi=n+1;
            first=1;
            while(ncount!=n){//n个人全被处理完毕//处理手法有些类似快速排序
                kcount=0;
                mcount=0;
                //每数一个人,都要判断是不是该越过他.只有0(未领过,才计数)
                while(kcount!=k){//k系列处理 
                    ki++;
                    if(ki>n)//ki越界处理 
                        ki=1;
                    if(book[ki]==0)//未被选中计数  ki为当前值 
                        kcount++;
                    
                }
                while(mcount!=m){//m系列处理 
                    mi--;
                    if(mi<1)//mi越界处理 
                        mi=n; 
                    if(book[mi]==0)//未被选中计数 mi为当前值 
                        mcount++;
            }
                book[ki]=1;//不用担心ki==mi(重复设置为1不影响)
                book[mi]=1; 
                
                if(first){//打印处理
                    first=0;
                    if(ki!=mi){
                        printf("%3d%3d",ki,mi);
                        ncount+=2;
                    }
                    else{
                        printf("%3d",ki); 
                        ncount++;
                    }
                }else{
                    if(ki!=mi){
                        printf(",%3d%3d",ki,mi);
                        ncount+=2;
                    }
                    else{
                        printf(",%3d",ki);
                        ncount++;
                    }
                }
            }
            printf("
    ");
        }
        return 0;
    }
    
    书上做法
    #include <stdio.h>
    #include <string.h>
    
    #define maxn 25
    
    int n,k,m,a[maxn];
    
    int go(int p,int d,int t)
    {
        while(t--)	//每数一个人都要判断他是否已经领过
        do{
            p = (n+p+d)%n;
        }while(!a[p]);	//==0,领过
        return p;
    }
    
    int main()
    {
        while(scanf("%d,%d,%d",&n,&k,&m)==3 && n)
        {
            for (int i = 0; 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("%d",p1);left--;
                if(p1!=p2) printf(" %d",p2);
                a[p1]=a[p2]=0;				//领了设置为0
                if(left) printf(",");		//注意输出格式
            }
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    Springboot + Caffeine 实现本地缓存
    springboot + mybatis-plus + sharding-jdbc 实现单库分表
    工厂模式+策略模式 使用
    JAVA 金额自动除以100,精确到分
    spring aop + 自定义注解实现本地缓存
    springboot 使用 retry重试机制
    Mybatis-plus 自动注入公共字段
    docker 安装kafka
    ES 实现聚合分页
    Authentication token manipulation error 及 mongodb WiredTigerLAS.wt 文件过大问题
  • 原文地址:https://www.cnblogs.com/nymrli/p/9571528.html
Copyright © 2020-2023  润新知