第八届湘潭大学程序设计比赛

A Love Letter

     

 

题目描述

  CodeMonkey终于下定决心用情书的方式向心爱的女神表白,当他历经几天几夜写完之后才知道女神有很多不喜欢的词,所以他不得不有把这些词删掉。例如:原文是:ILOVEYOU,女神不喜欢的词是‘LV’,‘O’那么最终情书要改成IEYU。现在已知女生不喜欢的词的集合S,CodeMonkey想知道刚写的情书会改成什么样?S={“HATE”,“SHIT”,“LV”,“O”,“FUCK”,“UGLY”,“MM”}

输入

  多样例输入,每个样例输入一行情书原文,原文只包含大写英文字母,原文长度不超过1000

输出

  对于每个样例,若是情书被删完则输出一行“LOSER”,否则输出情书的剩余内容

样例输入
ILOVEYOU
MM

样例输出
IEYU
LOSER
 
string text ;
vector<string>word  ;
char str[1008] ;
bool cango[1008] ;
void Go(int indx ,string s){
    int i , j ;
    i = indx ;
    j = 0 ;
    while(i < text.length() && j < s.length() && text[i] == s[j]){
         i++ ;
         j++ ;
    }
    if(j == s.length()){
        for(i = indx ; i < indx + s.length() ; i++)
            cango[i] = 0 ;
    }
}

void Gao(){
     int i , j ;
     memset(cango , 1 , sizeof(cango)) ;
     for(i = 0 ; i < word.size() ; i++){
        for(j = 0 ; j < text.length() ; j++){
             if(cango[j])
                 Go(j , word[i]) ;
        }
     }
     string ans  = "" ;
     for(i = 0 ; i < text.length() ; i++){
         if(cango[i])
             ans += text[i] ;
     }
     if(ans.size() == 0){
         puts("LOSER") ;
         return ;
     }
     if(ans == text){
         cout<<ans<<endl ;
         return ;
     }
     else{
          text = ans ;
          Gao() ;
     }
}

int main(){
    word.clear() ;
    word.push_back("HATE") ;
    word.push_back("SHIT") ;
    word.push_back("LV") ;
    word.push_back("O") ;
    word.push_back("FUCK") ;
    word.push_back("UGLY") ;
    word.push_back("MM") ;
    while(gets(str)){
        text = string(str) ;
        Gao() ;
    }
    return 0 ;
}

Bob's Problem

     

题目描述

Bob今天碰到一个问题,他想知道x3+y3 = c 是否存在正整数解?

输入

第一行是一个整数K(K≤20000),表示样例的个数。 以后每行一个整数c(2≤c≤109)

输出

每行输出一个样例的结果,如果存在,输出“Yes”,否则输出“No”。(引号不用输出)

样例输入
2
28
27

样例输出
Yes
No
set<int> pow3 ;
int p3[1008] ;
void init(){
     pow3.clear() ;
     for(int i = 1 ; i <= 1000 ; i++){
        p3[i] = i*i*i ;
        pow3.insert(p3[i]) ;
     }
}

int judge(int c){
    int i ;
    for(i = 1 ; p3[i]<= c ; i++){
        if(pow3.find(c - p3[i]) != pow3.end()){
            return 1 ;
        }
    }
    return 0 ;
}

int main(){
     init() ;
     int t , x ;
     scanf("%d" , &t) ;
     while(t--){
          scanf("%d" , &x) ;
          printf("%s\n" ,judge(x)? "Yes" : "No") ;
     }
     return 0 ;
}

Cipher Lock

     

题目描述

守护着神秘宝藏One Piece的是一把非常神秘的密码锁,这个密码锁有n排滚轮,每个滚轮有m个格子,刻着0,1两种数字。作为一把神秘的密码锁,开锁的方式却非常的简单,只要向左或向右转动滚轮使某一列的数字全是1就可以了。(向左滚动:所有的数字向左移动一位,最左边的数字移动到最右边,如001100左滚动一次变为011000,向右滚动与向左滚动操作相同,只是方向相反),作为即将成为海贼王的你,一定会选择最帅气的开锁方式———既用最少的次数来打开守护着神秘宝藏One Piece的密码锁。那么,请问最帅气的开锁次数需要转动密码锁几次呢?

输入

有多组数据输入,每个数据第一行为两个整数n,m表示有n排密码锁,每个密码锁有m个格子,其中(1≤n≤100,1≤m≤104)。接下来的有n行输入,表示每排密码锁的初始状态。

输出

对每组数据输出两行,第一行输出“Case # :”表示当前是几号样例(从1开始编号),第二行,如果可以开锁就输出一个整数表示最少需要移动几次,否则输出“Give Me A BOOM please”。(均不用输出“”号)

样例输入
2 3
111
000
3 6
101010
000100
100000

样例输出
Case #1:
Give Me A BOOM please
Case #2:
3

提示

对第一个样例,不可能开锁。第二个样例,可以第2行向左滚动一次,第3行向右滚动2次,最少3次就可以解锁。

char str[108][10008] ;
int  dp[108][10008] ;
const int inf = 3000000 ;
int N , M ;

int DP(){
    int ok , i , j , indx , first_1 , last_1;
    for(i = 1 ; i <= N ; i++){
       ok = 0 ;
       first_1 = -1 ;
       for(j = 1 ; j <= M ; j++){
           dp[i][j] = inf ;
           if(str[i][j] == '1'){
               ok = 1 ;
               if(first_1 == -1)
                   first_1 = j ;
               last_1 = j ;
           }
       }
       if(!ok)
           return inf ;
       indx = -(M-last_1) ;
       for(j = 1 ; j <= M ; j++){
           if(str[i][j] == '1'){
                indx = j ;
                dp[i][j] = 0 ;
           }
           else
                dp[i][j] = j - indx ;
       }
       indx = M + first_1 ;
       for(j = M ; j >= 1 ; j--){
           if(str[i][j] == '1'){
               indx = j ;
               dp[i][j] = 0 ;
           }
           else{
               if(indx != -1)
                    dp[i][j] = min(dp[i][j] , indx - j) ;
           }
       }
    }
    int ans = inf  , now ;
    for(j = 1 ; j <= M ; j++){
        now = dp[1][j] ;
        for(i = 2 ; i <= N ; i++)
            now += dp[i][j] ;
        ans = min(ans , now) ;
    }
    /*for(i = 1 ; i <= N ; i++){
        for(j = 1 ; j <= M ; j++)
            printf("%d  ", dp[i][j]) ;
        puts("") ;
    }*/
    return ans ;
}

int main(){
    int i , k = 1;
    while(scanf("%d%d" , &N ,&M)!=EOF){
        for(i = 1 ; i <= N ; i++)
            scanf("%s" ,str[i]+1) ;
        printf("Case #%d:\n" , k++) ;
        int ans = DP() ;
        if(ans == inf)
            puts("Give Me A BOOM please") ;
        else
            printf("%d\n" , ans) ;
    }
    return 0 ;
}

Double Maze

     

题目描述

一个迷宫里,有两个点,你的任务是给出尽可能短的一系列的命令,让这两个点一起执行这些命令能走到一起。如果某个点按某个命令走会走出迷宫或走到障碍上,则忽略这条命令。

输入

输入不超过1000个样例,每个样例第一行有两个整数n,m(2≤n,m≤11),之后n行每行m个字符,'.'表示能走的地方,'#'表示障碍,‘*'表示其中一个点。每个样例之间有一个空行。

输出

每个样例输出一行,包含'U','D','L','R'。'U'表示向上走的命令,'D'表示向下,'L'表示向左,'R'表示向右。要是有多个答案,输出字典序最小的序列。如果无法达到目标,输出“Sorry”(引号不要输出)。

样例输入
4 11
*.##..#..#*
...#..#.#..
.##.#.#.##.
##..###....

4 4
.*..
.###
...*
....

10 10
*.........
#########.
..........
.#########
..........
#########.
..........
.#########
.........*
##########

样例输出
Sorry
LLLUU
LLLLLLLLLUURRRRRRRRRUULLLLLLLLLUURRRRRRRRRDD
 
int n , m ;
struct Node{
       int x1 ,x2 ,y1 , y2 ;
       int step ;
       string ans ;
       Node(){} ;
       Node(int a,int b,int c ,int d,int e ,string s):x1(a),y1(b),x2(c),y2(d),step(e),ans(s){}
       friend bool operator < (const Node &A ,const Node &B){
            if(A.step == B.step)
                return A.ans > B.ans ;
            else
               return A.step > B.step ;
       }
};

char str[13][13] ;
int d[4][2] = {{1,0},{0,-1},{0,1},{-1,0}} ;
int step[13][13][13][13] ;
const int inf = 100000000 ;

int  cango(int x ,int y){
     return 1 <= x && x <= n && 1 <= y && y <= m && str[x][y] != '#' ;
}

string spfa(Node start){
     int i , j , k , p ;
     for(i =  1 ; i <= n ; i++)
        for(j = 1 ; j <= m ; j++)
           for(k = 1 ; k <= n ; k++)
               for(p = 1 ; p <= m ; p++)
                   step[i][j][k][p] = inf ;
     priority_queue<Node> que ;
     que.push(start) ;
     //printf("%d %d %d %d\n", start.x1 , start.y1,start.x2 ,start.y2) ;
     step[start.x1][start.y1][start.x2][start.y2] = 0 ;
     while(!que.empty()){
          Node now = que.top() ;
          que.pop() ;
          if(now.x1==now.x2 && now.y1==now.y2)
                    return now.ans ;
          for(i = 0 ; i < 4 ; i++){
               int x1 = now.x1 + d[i][0] ;
               int y1 = now.y1 + d[i][1] ;
               int x2 = now.x2 + d[i][0] ;
               int y2 = now.y2 + d[i][1] ;
               int stp = now.step + 1 ;
               if(!cango(x1,y1) && !cango(x2,y2))
                   continue ;
               if(!cango(x1,y1)){
                   x1 = now.x1 ;
                   y1 = now.y1 ;
               }
               if(!cango(x2,y2)){
                   x2 = now.x2 ;
                   y2 = now.y2 ;
               }
               if(stp < step[x1][y1][x2][y2]){
                    step[x1][y1][x2][y2] = stp ;
                    string nx = now.ans ;
                    if(i == 0)
                        nx += "D" ;
                    else if(i == 1)
                        nx += "L" ;
                    else if(i == 2)
                        nx += "R" ;
                    else
                        nx += "U" ;
                    que.push(Node(x1,y1,x2,y2,stp,nx)) ;
               }
        }
    }
    return "Sorry" ;
}

int main(){
    int i , j ;
    while(scanf("%d%d" ,&n,&m)!=EOF){
        for(i = 1 ; i <= n ; i++)
            scanf("%s", str[i]+1) ;
        Node start ;
        start.x1 = - 1 ;
        start.step = 0 ;
        start.ans = "" ;
        for(i = 1 ; i <= n ; i++){
            for(j = 1 ; j <= m ; j++){
                if(str[i][j] == '*' ){
                   if(start.x1 == -1){
                      start.x1 = i ;
                      start.y1 = j ;
                   }
                   else{
                      start.x2 = i ;
                      start.y2 = j ;
                   }
                }
            }
        }
       // printf("%d %d %d %d\n", start.x1 , start.y1,start.x2 ,start.y2) ;
        cout<<spfa(start)<<endl ;
    }
    return 0 ;
}

Flappy Bird

Accepted : 12 Submit : 50
Time Limit : 1000 MS Memory Limit : 65536 KB

题目描述

Henry最近迷上Flappy Bird这个小游戏,这个需要不断控制点击屏幕的频率来调节小鸟的飞行高度和降落速度,让小鸟顺利地通过画面右端的通道,如果不小心撞到了通道的话,游戏便宣告结束。 我们来简化一下这个游戏,如图所示,画面的高度为17,通道的宽度为2,上下通道之间所留的空间长度始终为3,每相邻的两个通道之间相距4个单位,小鸟占据单位1的面积,且始终向画面右端移动,每秒移动1列。我们可以在这一秒内控制小鸟上升、下降或者维持在原有的高度不变。每当小鸟通过了一个通道(即完全穿越过这个通道),便获得1分,当小鸟撞击到了通道,游戏结束。 在通过第一个通道之前,Henry可以凭借他犀利的操作使小鸟处于任意的高度。 现在Henry已经得到了通道的排布情况,他希望聪明的你能告诉他最多能获得的分数。 

输入

第一行为1个整数T,表示样例的个数。 每个样例的第一行是一个整数N(1≤N≤500), 接下来有N行,每行两个整数x,y,分别表示上通道的底部和下通道的顶部所在 的格子的位置,(8≥x>y≥-8, x-y-1=3)

输出

对于每个样例输出一行,表示小鸟所得的分数, 如果小鸟能通过所有的通道,则输出win

样例输入
2
2
2 -2
4 0
3
2 -2
-2 -6
8 4

样例输出
win
2


struct Node{
       int x ;
       int up ;
       int down ;
       Node(){} ;
       Node(int a , int i , int j):x(a),up(i),down(j){}
       void read(){
            scanf("%d%d",&up,&down) ;
       }
       void out(){
            printf("---%d:(%d  ,  %d)   ",x , up , down) ;
       }
};

int DP(vector<Node> &List){
    int i , dist , up , down ;
    Node now = Node(List[0].x , List[0].up-1 , List[0].down+1)  ;
    for(i = 1 ; i < List.size() ; i++){
        dist = List[i].x - List[i-1].x ;
        if(dist == 1){
            up = now.up + 1 ;
            down = now.down - 1 ;
            if(up <= List[i].down)
                return i ;
            if(down >= List[i].up)
                return i ;
            if(up >= List[i].up)
                up = List[i].up -1  ;
            if(down <= List[i].down)
                down = List[i].down + 1;
            now = Node(List[i].x , up , down) ;
        }
        else{
            up = now.up + 5 ;
            down = now.down - 5 ;
            if(up <= List[i].down)
                return i ;
            if(down >= List[i].up)
                return i ;
            if(up >= List[i].up)
                up = List[i].up -1 ;
            if(down <= List[i].down)
                down = List[i].down + 1 ;
            now = Node(List[i].x , up , down) ;
        }
    }
    return i ;
}

int main(){
    vector<Node> List ;
    vector<Node> ::iterator it ;
    Node node ;
    int t , n  , x ;
    cin>>t ;
    while(t--){
        cin>>n ;
        List.clear() ;
        x = 0 ;
        while(n--){
            node.read() ;
            node.x = x ;
            List.push_back(node) ;
            x++ ;
            node.x = x ;
            List.push_back(node) ;
            x += 5 ;
        }
        int ans = DP(List) ;
        if(ans == List.size())
           puts("win") ;
        else
           printf("%d\n" , ans>>1) ;
    }
    return 0 ;
}






Game of Wuxing

     

题目描述

“五行”是中国传统哲学思想,它认为大自然的现象由“木、火、土、金、水”这五种气的变化所总括, 不但影响到人的命运,同时也使宇宙万物循环不已。 五行具有相生相克的性质,规律如下:

  • 五行相克:金克木,木克土,土克水,水克火,火克金。
  • 五行相生:金生水,水生木,木生火,火生土,土生金。
  • 五行任一行与其他五行的关系为:同我、生我、我生、克我、我克。


传说古代有一种游戏,有一些骨牌,骨牌上刻有五行属性和点数(点数从1到9)。 游戏时,甲和乙各抽5张骨牌,然后每轮,两人各出一张牌,翻开以后比较:

  • 如果甲和乙构成同我关系,则两人各得自己牌的得分;
  • 如果甲和乙构成生我关系(即乙生甲),比如说甲出金,乙出土,那么两张牌的点数之和为甲的得分;
  • 如果甲和乙构成我克关系(即甲克乙),比如说甲出金,乙出木,那么两张牌的点数之差(绝对值)为甲的得分;

最后得分多者为胜。 现在给你甲和乙的出牌顺序,请计算一下游戏的结果。

 

输入

第一行是一个整数K,表示样例的个数。 以后每个样例占5行,为5次出的牌。每行按甲乙的顺序给出牌。 每张牌的类型,即金木水火土分别使用J、M、S、H、T5个大写英文表示。 点数使用数字1-9表示。 两牌之间有一个空格。

输出

每个样例输出一行,如果甲胜输出“Jia”,乙胜输出“Yi”,平局输出“Ping”。(不要输出引号)。

样例输入
3
J1 J1
J1 M1
J1 S1
J1 H1
J1 T1
J1 J1
J1 M2
J1 S3
J1 H4
J1 T6
J1 J1
J1 M2
J1 S3
J1 H4
J1 T4


样例输出
Ping
Jia
Yi
char thing[5]= {'J' , 'M' , 'S' , 'H' , 'T'} ;
map<char , char> Tongwo , Shengwo , Woke ;

void init(){
     Tongwo.clear() ;
     Shengwo.clear() ;
     Woke.clear() ;
     int i ;
     for(i = 0 ; i < 5 ; i++)
          Tongwo[thing[i]] = thing[i] ;
     Woke['J'] = 'M' ;
     Woke['M'] = 'T' ;
     Woke['T'] = 'S' ;
     Woke['S'] = 'H' ;
     Woke['H'] = 'J' ;
     Shengwo['J'] = 'S' ;
     Shengwo['S'] = 'M' ;
     Shengwo['M'] = 'H' ;
     Shengwo['H'] = 'T' ;
     Shengwo['T'] = 'J' ;
}

int A_sum , B_sum ;

void gao(string A , string B){
     char a = A[0] ;
     char b = B[0] ;
     int  i = A[1] - '0' ;
     int  j = B[1] - '0' ;
     if(a == b){
         A_sum += i ;
         B_sum += j ;
     }
     else if(Shengwo[b] == a){
         A_sum += (i+j) ;
     }
     else if(Shengwo[a] == b){
         B_sum += (i+j) ;
     }
     else if(Woke[a] == b){
         A_sum += abs(i-j) ;
     }
     else if(Woke[b] = a){
        B_sum += abs(i-j) ;
     }
}

int main(){
    init() ;
    int i , t ;
    string a , b ;
    cin>>t ;
    while(t--){
        A_sum = B_sum = 0 ;
        for(i = 0 ; i < 5 ; i++){
            cin>>a>>b ;
            gao(a,b) ;
        }
        if(A_sum > B_sum)
            puts("Jia") ;
        else if(A_sum == B_sum)
            puts("Ping") ;
        else
            puts("Yi") ;
    }
    return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值