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

来源:互联网 发布:ubuntu 交叉编译 编辑:程序博客网 时间:2024/06/05 02:28

菜鸟程设 A题日志》第三周

用以悼念我的国庆。

第九题 唬人的格子

现在觉得很多题把题意吃透了题就做出一半了,此题尤为如此。http://acm.uva.es/p/v7/795.html

那个英雄厉害之处就再于那个筛密码格转4下,空格就正好把正方形填满。(这个白空格还有其他组合方式么?)于是照着每次旋转后从左上到右下按顺序填密码,可以得到一个不变的先后序列矩阵,即KK神的某给力跟帖。先把乱码置成前一步骤的矩阵,然后照着对应序列矩阵的号码顺序,在每个长度为36的密码串的数组下标置存入即可。

#include"stdio.h"
#include "string.h"
int main(){
 int key[36] = { 28, 1,19, 2,29,3, 20,30,10,31, 4,11, 32,21,5,12,22,33, 13, 6,34,23,7,14, 35,24,15,36,16,8, 25,17,26, 9,27,18};
 int i=0,j=0,times=0,n=0;
 charinp[110]="",secret[6][7],result[110]="";
 while(gets(inp)!=NULL){
  times=strlen(inp)/36;
  for(n=0;n<times;n++){
   for(i=0;i<6;i++){
    for(j=0;j<6;j++){
     secret[i][j]=inp[n*36+i*6+j];
    }
   }
   for(i=0;i<6;i++)
   {
    for(j=0;j<6;j++){
     result[n*36+key[i*6+j]-1]=secret[i][j];
    }
   }
   memset(secret,'\0',sizeof(secret));
  }
  memset(inp,'\0',sizeof(inp));
  for(i=times*36-1;i>=0;i--){
   if(result[i]!='#')
    printf("%c",result[i]);
   else
    break;
  }
  printf("\n");
 }
 return 0;
}

第十题 神人神法领悟即可http://www.bianchengla.com/team/27/practise/problem?id=1577

在自己的智力面前,很多原则还是需要让一让。

比如这种题不看各路神牛的经验方法,不各种问各种学我是理解不了的。

最终用的是省时省力不省脑的琛神三维魔方数组法(借用晨曦的比喻)。

很多人都说的很明白了,只是到了最后我还是不懂每个小格子里存的是神马,在豪绅的点拨下终于明白是每个字出现的次数。而每个字编码的不变位(XX位)则是对应的数组下标。于是豁然开朗,劈WAA

#include"stdio.h"
#include "string.h"
int main(){
 unsigned char part,word[3]="";
 intsave[17][64][64],i=0,j=0,k=0,flag=0,illegal=0;
 memset(save,0,sizeof(save));
 while((scanf("%c",&part))!=EOF){
  if(part<=128){
   continue;
  }
  else{
   if(part>=192&&part<224){
    word[0]=part;
    part=getchar();
    if(part>=128&&part<192){
     word[1]=part;
     save[0][word[0]-192][word[1]-128]++;
    }
    else{
     illegal++;
    }
   }
   elseif(part>=224&&part<240){
    word[0]=part;
    part=getchar();
    if(part>=128&&part<192){
     word[1]=part;
     part=getchar();
     if(part>=128&&part<192){
      word[2]=part;
      save[word[0]-223][word[1]-128][word[2]-128]++;
     }
     else
     {illegal++;
     }
    }
    else
    {illegal++;
    }
   }
  
 }
 for (i=0;i<17;i++){
  for(j=0;j<64;j++){
   for(k=0;k<64;k++){
    if(save[i][j][k]>=2){
     if(i==0){
      printf("%c%c%d\n",j+192,k+128,save[0][j][k]);
      flag++;
     }
     else{
      printf("%c%c%c%d\n",i+223,j+128,k+128,save[i][j][k]);
      flag++;
     }
    }
   }
  }
 }
 if (flag==0)
 {printf("No repeat!\n");
 }
 if(illegal!=0){
  printf("Illegal charactercount:%d\n",illegal);
 }
 return 0;
}

第十一题 最牛的回文

据说,如果有无穷多的母牛和无穷多的大型键盘,它们就可以创造出世界上最伟大的回文。在寻找回文时,可以不计文中的标点、空白和大小写,只要关注26 个英文字母就可以了。但是要注意,在输出时要按照原样,也就是要保留原有的空白、标点和大小写。

你的任务,就是在不超过 20000 个字符的字符串中,寻找长度不超过 2000 的回文字符串(含空格和标点时)。

输入格式

一段文本,不超过 20000 个字符,可以有一行或多行,每行的长度不超过 80 个字符。

输出格式

输出的第一行为找到的最长的回文字符串的长度。后面的行应该包括该字符串,字符串两边多余的空格和标点都不需要输出,但字符串中的空格、标点和换行则需要按照原样输出。

如果文中有多个长度相同的回文字符串,只要输出第一个就可以了。

最艰难的一题,三个版本,4个工程,无数用例,几近崩溃。说到底还是方法用错了。

第一版本是可怜的递归,还是用两边往中间判断,超时与错误一票。

第二版是可悲的马拉车Manacher算法,刚看懂的时候觉得本题的众多标点符号已经完全破坏了算法所要求的对称性,结果思索之后觉得可以再设一个对应原串的辅助数组pr,只要将p中的数字对应赋给pr就可以应用了。结果就是这简单的思想,让我功败垂成,其间处理令我头晕脑胀,基本浪费了一天。如有用马拉车成功的可以留贴交流http://blog.csdn.net/ggggiqnypgjg/article/details/6645824马拉车算法。

第三版才是无奈地回归群众,从中间往两边暴力,无压力迅速解开心结。

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int main()
{
 char c,str[21000]="",str1[21000]="";
 int length[20000],p[20000];
 inti=1,j=1,k=0,midpos=0,len=0,p1=0,pm=0,p3=0,max=0,first=0,last=0;
 memset(p,0,sizeof(p));
 memset(length,0,sizeof(length));
 while ((c=getchar())!=EOF){
  str[i]=c;
  if(tolower(c)>='a'&&tolower(c)<='z')
  {
   str1[j]=tolower(c);
   p[j]=i;
   j++;
  }
  i++;
 }
 for (pm=1;pm<j;pm++)
 {
  if(str1[pm-1]!=str1[pm]&&str1[pm-1]==str1[pm+1])
  {
   p1=pm-1;
   p3=pm+1;
   len=1;
   while(str1[p1]==str1[p3]){
    len+=2;
    p1--;
    p3++;
   }
   if(p[p3-1]-p[p1+1]+1<=2000)
   {
    length[pm]+=len;
   
  }
  else if(str1[pm-1]==str1[pm])
  {
   p1=pm-2;
   p3=pm+1;
   len=2;
   while(str1[p1]==str1[p3]&&(str1[p1]>='a'&&str1[p1]<='z')){
    len+=2;
    p1--;
    p3++;
   }
   if(p[p3-1]-p[p1+1]+1<=2000)
   {
    length[pm]+=len;
   }
  }
  else{
   length[pm]=1;
  }
 }
 for (k=1;k<j;k++)
 {
  if(length[k]>max)
  {
   max=length[k];
   midpos=k;
  }
 }
 printf("%d\n",max);
 if (max%2==0)
 {
  first=p[midpos-max/2];
  last=p[midpos+max/2-1];
 }
 else
 {
  first=p[midpos-(max-1)/2];
  last=p[midpos+(max-1)/2];
 }
 for (i=first;i<=last;i++)
 {
  printf("%c",str[i]);
 }
 printf("\n");
 return 0;
}

第十二题 破朔迷离的关键词

直接说疑惑吧,UVA原题的叙述http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=3&problem=111&mosmsg=Submission+received+with+ID+9325157the numbers of the selected titles in numericalorder, separated by commas and with no spaces.”此句与网教题目中“词与词之间以空格、换行或标点符号分隔。”相比少了标点符号分隔这句。但是接下来的用例中一些可以被称作标点符号的(  )  -  --- 都感觉不算可以分隔的标点,于是不明真相的群众们诚惶诚恐狂刷UVArejudge,求真相。

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
char p[50][20][25],t[250][100][25];
int mark[250][100];
int main(){
 char pot,psg;
 intmidlen[50],result[100],pflag=0,tflag=0,variable[90],len=0,v1=0,v2=0,v3=0,vflag=0;
 int i=0,j=0,k=0,x=0,y=0,z=0;
 int m=0,n=0,a=0,b=0;
 int count=0,countword=0,times=0,t1=0;
 memset(p,'\0',sizeof(p));
 memset(t,'\0',sizeof(t));
 memset(midlen,0,sizeof(midlen));
 while((pot=getchar())!='#'){  
  if (pot=='P'){
   scanf(":%d",&midlen[i]);
   while((psg=getchar())!=10){
    if((psg>='a'&&psg<='z')||(psg>='A'&&psg<='Z')){
     if(pflag==0){
      pflag=1;
      
     }
     p[i][j][k]=psg;
     k++;
    }
    elseif(psg==' '||psg==10){
     if(pflag==1){
      pflag=0;
      j++;
      k=0;
     }
    }
   }
   i++;j=0;k=0;pflag=0;
  }
  else if(pot=='T'){
   while((psg=getchar())!='|'){
    if((psg>='a'&&psg<='z')||(psg>='A'&&psg<='Z')){
     if(tflag==0){
      tflag=1;
     }
     t[x][y][z]=tolower(psg);
     z++;
    }
    elseif(psg==' '||psg==10){
     if(tflag==1){
      tflag=0;
      y++;
      z=0;
     }
    }
   }x++;y=0;z=0;tflag=0;
  }
 
 for (m=0;m<i;m++){
  memset(mark,0,sizeof(mark));
  memset(result,0,sizeof(result));
  j=0;
  while (p[m][j][0]!='\0'){
   j++;
  }
  for(n=0;n<j;n++){
   y=0;
   for(a=0;a<x;a++){
    while(t[a][y][0]!='\0'){
     y++;
    }
    for(b=0;b<y;b++){
     if(strcmp(p[m][n],t[a][b])==0){
      mark[a][b]=n+1;
     }
    }
   }
  }
  for(a=0;a<x;a++){ 
   y=0;
   while(t[a][y][0]!='\0'){
    y++;
   }
   if(y-2-midlen[m]>0){
    times=y-2-midlen[m];
   }
   elsetimes=1;
   
   for(b=0;b<=times;b++){
    v3=0;
    memset(variable,0,sizeof(variable));
    countword=0;
    t1=2+midlen[m]>y?y:2+midlen[m];
    for(count=0;count<t1;count++){
     if(mark[a][b+count]!=0){
      
      for(v1=0,vflag=0;v1<80;v1++){
       if(mark[a][b+count]==variable[v1]){
        vflag=1;break;
       }
      }
      if(vflag!=1){
       countword++;
       variable[v3]=mark[a][b+count];
       v3++;
      }
     }
    }
    if(countword>=2){
     result[a]=a+1;
     break;
    }
   }
  }
  printf("%d: ",m+1);
  for(count=0,t1=0;count<x;count++){
   if(result[count]!=0){
    t1++;
   }
  }
  for(count=0,pflag=0;count<x;count++){
   if(result[count]!=0){
    printf("%d",result[count]);
    pflag++;
    if(pflag<=t1-1)
    printf(",");
   }
   
  printf("\n");
 }
 return 0;
}

————————————————————准备吐槽的分割线——————————————

虽然做好了准备,并且很轻松地找到了数不清的出去玩不明智的理由,但是十一的痛苦程度还是出乎了我的意料,尤其是这阳光灿烂的日子,加上看到神牛们各种潇洒,让人内心不得不阴暗,真的从来没以这种心情过假期的。再加上平均每天10小时的电脑时间,这日子,基本就没人信(性)。

很想大声吐槽只是今儿没神马力气了~千言万语只作一首词

《编编程》

转自 何远健

 调调试试,反反复复,凄凄惨惨戚戚。乍REWA时候,最难AC。三番两次AC,怎敌他,晚来REJUDGE?折扣过,正伤心,却是被逼无奈。满地杯具堆积,人憔悴,如今有谁堪玩?守着本儿,独自怎生得AC!人儿更兼凉风,到深夜,WAWA去。这编程,怎一个愁字了得!

 

0 0
原创粉丝点击