菜鸟BIT程序设计课A题日志第一周

这篇博客记录了作者在BIT程序设计课程中遇到的第一周题目,包括RPWT和Vito's Family两题的解题思路及遇到的问题。在RPWT题中,通过对比高低值数组判断Tom的回答是否自相矛盾,解决输入缓冲区问题。Vito's Family题中,通过计算所有路径总和找到最短距离。在解题过程中,作者意识到细节和递归条件的重要性,并分享了调试技巧和感悟。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要声明的是这几篇在BIT程设课期间写的,水平非常有限,算是自娱。

 

我也只能说些自身教训了,仅供菜鸟共勉。

第一题RPWT。看到第一题N多人提交数比后几题还多便深感RP重要性。输入方面大循环里scanf读入此次猜的数字,然后gets回答。结果缓冲区里回车被gets读入于是百度在gets之前加了fflush(stdin);清空缓冲区,忘了可以getchar()也不知道可以scanf(“\n”);之后琛神告知这种方法用不多且全清空可能会引起错误。之后就是字符串比较高了存一个数组,低的存另一个,两组循环判断如果答案比高的高或者比低的低就都会输出没RP。于是就WA了第二个。纠结几番觉得如果Jerry很二Tom5低了他猜3,结果Tom说高了,然后他猜4,对了,按之前的就会输出两个没RP,于是若有输出便标记一下,搞定。

描述

Tom 和 Jerry 做猜数字的游戏,Tom 想一个数字然后让 Jerry 去猜,数字的范围在 1 到 10 之间。对于 Jerry 每讲的一个数,Tom 都要讲这个数是 too high 或者 too low 或者 right on,直到 right on 结束。为了防止 Tom 作弊,Jerry 把每一次的对话记录下来,现在让你去判断 Tom 有没有作弊。

输入

游戏可能做很多次,直到 Jerry 猜 0 的时候游戏结束,每一次猜测由一个正整数和一行回答组成。

输出

对每一次游戏如果 Tom 的回答有自相矛盾的地方,就输出 Tom is dishonest,否则输出 Tom may be honest。

#include"stdio.h"
#include"string.h"
int main()
{
 int number=0,high[100]={0},i=0,low[100]={0},j=0,count=0,flag=0;
 char check[50]="";
 do
 {
  scanf("%d",&number);
  fflush(stdin);
  if(number<=10&&number>=1)
  {
   gets(check);
  }
  else
  {
   break;
  }

  if(strcmp(check,"too high")==0)
  {
   high[i]=number;
   i++;
  }
  else if(strcmp(check,"too low")==0)
  {
   low[j]=number;
   j++;
  }
  else if(strcmp(check,"right on")==0)
  {
   for(count=0;count<i;count++)
   {
    if(high[count]<=number&&flag!=1)
    {
     printf("Tom is dishonest\n");
     flag=1;
     break;     
    }
   }
   for(count=0;count<j;count++)
   {
    if(number<=low[count]&&flag!=1)
    {
     printf("Tom is dishonest\n");
     flag=1;
     break;
    }
   }
   if(flag==0)
   {
    printf("Tom may be honest\n");
   }
   memset(check, 0, 50);
   memset(high, 0, 100);
   memset(low, 0, 100);
   i=0;
   j=0;
  }
  flag=0;
 }while(number!=0);
 return 0;
}

 

第二题Vito's Familiy我果断想起教父,英文题就把题意搞错了,算了半天距离却输出的是可住的门牌号,而且不懂他只能住其中一个亲戚家,果断霸气让他任选一号住。英文差的伤不起。

Background

The world-known gangster Vito Deadstone is moving to New York. He has a very big family there, all of them living in Lamafia Avenue. Since he will visit all his relatives very often, he is trying to find a house close to them.

Problem

Vito wants to minimize the total distance to all of them and has blackmailed you to write a program that solves his problem.

Input

The input consists of several test cases. The first line contains the number of test cases.

For each test case you will be given the integer number of relatives r ( 0 < r < 500) and the street numbers (also integers) s0, s1, ..., si, ..., sr where they live ( 0 < si < 30000 ). Note that several relatives could live in the same street number.

Output

For each test case your program must write the minimal sum of distances from the optimal Vito's house to each one of his relatives. The distance between two street numbers si and sj is dij= |si-sj|.

#include"stdio.h"
#include"math.h"
int main()
{
 int times=0,n=0,number=0,i=0,j=0,streetno[500]={0},minus=0,compare[500]={0},flag=0,temp=0;
 long int result=0;
 scanf("%d",&times);
 for(n=0;n<times;n++)
 scanf("%d",&number);
 for(i=0;i<number;i++)
 {scanf("%d",&streetno[i]);
 }
 for(i = 0;i<number;i++)
 { minus = 0;
 for(j = 0;j < number;j++)
    {minus = fabs(streetno[i]-streetno[j]) + minus;
    }
    compare[i] = minus;
 }
 minus=429496729;
 for(j=0;j<number;j++)
 {if(compare[j]<minus)
  {minus=compare[j];
  }
 }printf("%d\n",minus);
 
 return 0;
}

第三题图形编辑器http://acm.uva.es/p/v102/10267.html真纠结。除了各种模拟麻烦外,改相反的坐标就改半天,当然耗时最长的是F指令。开始觉得可以循环判断目标点上下左右是否和原颜色相同,是就改色,直到填满,后来想到边界情况判断麻烦循环次数多就硬着头皮上递归。交上之后所有F指令用例RE。请教琛神一眼看出递归停止条件边界只判断了右边界和下边界。补上后倒数第二个保密RE。边逛讨论区边乱改,用getchar替代scanf处理垃圾数据,检查相同颜色染色,存位图名数组改大,输入格式检查,检查输入坐标超I指令规定范围……继续染红几次后终于A了。

#include <stdio.h>
#include <string.h>
int x,y,x1,y1,x2,y2,c=0,r=0,judge[300][300];
char command,color,graph[300][300],name[300]="";
int min(int a,int b)
{
    if(a>b)
 {
  a=b;
 }
    return a;
}
void Fill(int i,int j,char origin,char color)
{
     if(graph[i][j]!=origin||judge[i][j]||!c||!r)
  {
   return;
  }
     judge[i][j]=1;
     graph[i][j]=color;
     Fill(i-1,j,origin,color);
     Fill(i+1,j,origin,color);
     Fill(i,j-1,origin,color);
     Fill(i,j+1,origin,color);
}
int main()
{
    int temp;
    do
    {
       scanf("%c",&command);
       if(command=='I')
       {
          scanf("%d %d\n",&c,&r);
          for(int i=1;i<=r;i++)
             for(int j=1;j<=c;j++)
    {
     graph[i][j]='0';
    }
       }
    else if(command == 'C')
       {
          for(int i=1;i<=r;i++)
             for(int j=1;j<=c;j++)
    {
     graph[i][j]='0';
    }
       }
       else if(command=='L')
       {
          scanf("%d %d %c\n",&x,&y,&color);
          if(y<=r && x<=c)
             graph[y][x]=color;
       }
    else if(command=='V')
       {
          scanf("%d %d %d %c\n",&x,&y1,&y2,&color);
          if(y1>y2)
    {
     temp=y1;
     y1=y2;
     y2=temp;
    }
          y1=min(y1,r);
    y2=min(y2,r);
    x=min(x,c);
          for(int i=y1;i<=y2;i++)
    {
     graph[i][x]=color;
    }
       }
    else if(command=='H')
       {
          scanf("%d %d %d %c\n",&x1,&x2,&y,&color);
          if(x1>x2)
    {
     temp=x1;
     x1=x2;
     x2=temp;
    }
          y=min(y,r);
    x1=min(x1,c);
    x2=min(x2,c);
          for(int j=x1;j<=x2;j++)
    {
     graph[y][j]=color;
    }
       }
    else if(command=='K')
       {
          scanf("%d %d %d %d %c\n",&x1,&y1,&x2,&y2,&color);
          if(x1>x2)
    {
     temp=x1;
     x1=x2;
     x2=temp;
    }
          if(y1>y2)
    {
     temp=y1;
     y1=y2;
     y2=temp;
    }
          y1=min(y1,r);
    y2=min(y2,r);
          x1=min(x1,c);
    x2=min(x2,c);
          for(int i=y1;i<=y2;i++)
    {
     for(int j=x1;j<=x2;j++)
     {
      graph[i][j]=color;
     }
    }
       }
    else if(command=='F')
       {
          scanf("%d %d %c\n",&x,&y,&color);
          y=min(y,r); x=min(x,c);
          memset(judge,0,sizeof(judge));
          Fill(y,x,graph[y][x],color);
       }
    else if(command=='S')
       {

          scanf("%s",name);
          printf("%s\n",name);
          for(int i=1;i<=r;i++)
          {
             for(int j=1;j<=c;j++)
                printf("%c",graph[i][j]);
             printf("\n");
          }
       }
    else if(command=='X') break;
    }while(command!='X');
    return 0;
}

第四题分牌。虽然与第三题耗时差不多,但感觉顺多了。把合法牌类型和每个牌型判断函数化,主函数的任务就是》用函数判断是否合法》小写字母化》tjqka换成9之后的ascii码》判断是否是已有牌》存入牌堆》满五张》从小到大排序》按优先级多重if else调用函数,最里头的elseHigh Card。交上哇了倒二用例,琛神一上检查个有两张牌相同的Three-of-a-kind,错了。原先思路是两重循环检测相同的牌计数(为方便包括自身相同),则如果是对子,最终计数值肯定是5+2,类似,Three-of-a-kind肯定是5+2*3,但仅对另两张不同有效。于是因为之前排序了,所以改为判断前三张||中三张||后三张相同。虽然各种问题,但是函数化了感觉调试就顺手,即使改了半天还是感觉比较顺利。

背景

游戏公司老板准备开发一个人机交互的打牌游戏,项目组里每个人都分配了不同的工作。你现在负责的模块就是为计算机设计一个分牌程序,帮助计算机像人一样可以把分到的牌进行分类。

众所周知,一副扑克牌有四种花色(即方块、梅花、红桃和黑桃)和14个分值级别(即二、三、四、五、六、七、八、九、十、J、Q、K和A)。这里假设A是分值最高级别的。

程序每次读取一手五张牌,然后根据下列类别把手中的牌分类(列出的顺序依次是从最好类别到最坏类别):

  • Straight flush: 同花顺的牌(即顺序相连又都是同花色)
  • Four-of-a-kind: 四张相同的牌(四张牌级别相同)
  • Full house: 三张花色相同和两张花色相同的牌(三张牌是同样的花色,而另外两张牌是同样的花色)
  • Flush: 同花色的牌(五张牌是同花色的)
  • Straight: 同顺序的牌(五张牌的级别顺序相连)
  • Three-of-a-kind: 三张相同的牌(三张牌级别相同)
  • Two pairs: 两对子
  • Pair: 一对(两张牌级别相同)
  • High card: 其它牌(任何其它情况的牌)

如果一手牌有两种或多种类别,程序将选择最好的一种。

为了输入方面,这里把牌的级别和花色简化(字母不区分大小写):

级别:2 3 4 5 6 7 8 9 t j q k a 花色:c d h s 

输入

每组要求输入五张牌的内容,每张牌一行(格式参见上述类型英文名)。每次可以运行多组测试,如果输入为0而不是牌,则程序终止。如果用户输入非法牌或者输入同张牌两次,程序将把此牌忽略掉,产生报错信息(Duplicate card; ignored.或者Bad card; ignored.),然后要求输入另外一张牌。

#include"stdio.h"
#include"string.h"
#include"ctype.h"
char grade[2][19]={{'2','3','4','5','6','7','8','9','t','j','q','k','a',':',';','<','=','>','\0'},{'d','c','h','s','\0'}};
int i=0,j=0;
int compare(char * add)

 for(i=0;i<19;i++)
 
  if(*add==grade[0][i])
  
   for(j=0;j<9;j++)
   
    if(*(add+1)==grade[1][j])
    
     return 1;
     break;
    }
   }
  }
 }if(i==19)return 0;
}
int Straightflush(char * add)
{
 if(((*add+1==*(add+10))&&(*add+2==*(add+20))&&(*add+3==*(add+30))&&(*add+4==*(add+40)))&&(*(add+1)==*(add+11))&&(*(add+11)==*(add+21))&&(*(add+21)==*(add+31))&&(*(add+31)==*(add+41)))
  return 1;
 else return 0;
}
int Fourofakind(char * add)
{
 if((*add==*(add+10)&&*add==*(add+20)&&*add==*(add+30))||(*(add+40)==*(add+10)&&*(add+40)==*(add+20)&&*(add+40)==*(add+30)))
  return 1;
 else return 0;
}
int Fullhouse(char * add)
{
 int n=0,m=0,result=0;
 for(n=0;n<5;n++)
 {
  for(m=0;m<5;m++)
  {
   if(*(add+n*10+1)==*(add+m*10+1))
    result++;
  }
 }
 if(result==13)return 1;
 else return 0;
}
int Flush(char * add)
{
 if((*(add+1)==*(add+11))&&(*(add+11)==*(add+21))&&(*(add+21)==*(add+31))&&(*(add+31)==*(add+41)))
  return 1;
 else return 0;
}
int Straight(char *add)
{
 if((*add+1==*(add+10))&&(*add+2==*(add+20))&&(*add+3==*(add+30))&&(*add+4==*(add+40)))
  return 1;
 else return 0;
}
int Threeofakind(char *add)

 if((*(add)==*(add+10)&&*(add+10)==*(add+20))||(*(add+10)==*(add+20)&&*(add+20)==*(add+30))||(*(add+20)==*(add+30)&&*(add+30)==*(add+40)))
  return 1;
 else return 0;
}/////////////////////////////////////////
int Twopairs(char *add)
{
 int n=0,m=0,result=0;
 for(n=0;n<5;n++)
 {
  for(m=0;m<5;m++)
  {
   if(*(add+n*10)==*(add+m*10))
    result++;
  
 }if(result==9)
   return 1;
  else
   return 0;
}//////////////////////////////////////////
int Pair(char *add)
{
 int n=0,m=0,result=0;
 for(n=0;n<5;n++)
 {
  for(m=0;m<5;m++)
  {
   if(*(add+n*10)==*(add+m*10))
    result++;
  }
 }
 if(result==7)return 1;
 else return 0;
}////////////////////////////
int main()
{
 int len=0,cnum=0,flag=0;
 char judge[10]="",cards[5][10],temp[10]="",ch0,ch1;
 memset(cards,'\0',sizeof(cards));//置空
 do
 {
  gets(judge);
  if(judge[0]=='0')break;//输入进,判断数组
  len=strlen(judge); flag=0;//替换10JQKA;
  ch0=judge[0];    
  judge[0]=tolower(ch0);
  if(judge[0]=='t')judge[0]=':';
  if(judge[0]=='j')judge[0]=';';
  if(judge[0]=='q')judge[0]='<';
  if(judge[0]=='k')judge[0]='=';
  if(judge[0]=='a')judge[0]='>'; //赋值
  ch1=judge[1];
  judge[1]=tolower(ch1);   
  if(compare(judge)&&(len==2))//如果该牌不为错牌
  
   for(i=0;i<cnum;i++)
   
    if(strcmp(&cards[i][0],judge)==0)//如果该牌为重复的
    
     flag=1;
     printf("Duplicate card; ignored.\n");
     flag=1;
     break;
    }
   }
   if(flag==0)//合法牌
   {
    cards[cnum][0]=judge[0];
    cards[cnum][1]=judge[1];
    cnum++;
    if(cnum%5==0)//输入5个合法值时,各种判断
    cnum=0;
    for (i=0;i<4;i++)//从小到大冒泡排序
    {
     for(j=0;j<4-i;j++)
     {
      if(cards[j][0]>cards[j+1][0])
      
       strcpy(temp,&cards[j][0]);
       strcpy(&cards[j][0],&cards[j+1][0]);
       strcpy(&cards[j+1][0],temp);
      }
     }
    }
    if(Straightflush(&cards[0][0])!=1)
    {
     if(Fourofakind(&cards[0][0])!=1)
     {
      if(Fullhouse(&cards[0][0])!=1)
      {
       if(Flush(&cards[0][0])!=1)
       {
        if(Straight(&cards[0][0])!=1)
        {
         if(Threeofakind(&cards[0][0])!=1)
         {
          if(Twopairs(&cards[0][0])!=1)
          {
           if(Pair(&cards[0][0])!=1)
           {
            printf("High card\n");
           }else printf("Pair\n");             
          }else printf("Two pairs\n");
         }else printf("Three-of-a-kind\n");
        }else printf("Straight\n");                 
       }else printf("Flush\n");
      }else  printf("Full house\n");
     }else  printf("Four-of-a-kind\n");
    }else printf("Straight flush\n");
    memset(cards,'\0',sizeof(cards));
    flag=0;
    }
   }
  }
  else
  printf("Bad card; ignored.\n");
  continue;
  }
 }while(judge[0]!='0');
 return 0; 
}

 

--------------------------滑水的分割线-----------------------------

       看到寝室的花了半天多在近凌晨A完最后一道兴奋地冲出门大吼我A~真心感到“A了”是世界上最美的一句话。在开题第二天全寝都A了也不容易。想暑假没去ACM基地来时实在觉得落后好多,不过在寝室大神们的激励下,小学期试水了下POJHDU,适应了一些。相信我们菜鸟们会熬过来,至少会成为学妹眼中的大神,到她们考C得时候哇哈哈!

咳咳,水毕,礼毕。

PS:洛阳亲友如相问,就说我在写代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值