codeforce 192 div2解题报告

今天大家一起做的div2,怎么说呢,前三题有点坑,好多特判....

A. Cakeminator

题目的意思是说,让你吃掉cake,并且是一行或者一列下去,但是必须没有草莓的存在。这道题目,就是判断一下每行和每列的情况,看是不是有草莓存在,有的话就标记一下。后面就直接把木有草莓的行和列求和再减去重复路过的cake就行,不过你第一遍写的比较麻烦,小数据过了,后来WA了,现在改了一种写法。就是简单的加加减减。上代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
using namespace std;
int n, m;
char sp[200][200];
int x[200];
int y[200];
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i< n; ++i)
        scanf("%s", sp[i]);
    memset(x, 0, sizeof(x));
    memset(y, 0, sizeof(y));
    int sumxs = 0, sumys = 0;
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            if(sp[i][j] == 'S')
            {
                x[i] = 1;
                sumxs++;
                break;
            }
        }
    }
    for(int i = 0; i < m; ++i)
        for(int j = 0; j <n; ++j)
        {
            if(sp[j][i] == 'S')
            {
                y[j] =1;
                sumys++;
                break;
            }
        }
    //cout << sumxs << ' ' << sumys <<endl;
    int cnt = 0;
    cnt += (n-sumxs)*m;
    cnt += (m-sumys)*n;
    //cout << cnt <<endl;
    cnt -= ((n-sumxs)*(m-sumys));
    cout << cnt <<endl;
    return 0;
}

B. Road Construction

题目的意思是说现在给你n个点,然后在给你m个关系,这m个个关系表示某两条边之间不能连边,问你求最短的建筑方案是什么,要求任意两点之间距离不能超过2.

这道题目当时纠结了很久,不知道怎么去链接,后面才想到这只能是所有的点围在一个点的周围的情况。其它的总会有两点之间的距离超过2的。所以就简单了,直接找到可以和任何一个点相连的点,输出他和剩下的点的序列就行了 。

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
using namespace std;
char sp[200][200];
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i)
        scanf("%s", sp[i]);
    int hang = 0;
    int sum[10000];
    int k = 0;
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < n; ++j)
        {
            if(sp[i][j] == '.')
            {
                //cout << i << ' ' << j <<endl;
                hang++;
                sum[k++] = i+1;
                sum[k++] = j+1;
                break;
            }
        }
    }
    if(hang == n)
    {
        for(int i = 0; i < k-1; i+=2)
            printf("%d %d\n", sum[i], sum[i+1]);
    }
    else
    {
        int lie = 0;
        k = 0;
        for(int i = 0; i < n; ++i)
        {
            for(int j = 0; j < n; ++j)
            {
                if(sp[j][i] == '.')
                {
                    //cout << i << ' ' << j <<endl;
                    lie++;
                    sum[k++] = j+1;
                    sum[k++] = i+1;
                    break;
                }
            }
        }
        if(lie < n)
            printf("-1\n");
        else
        {
            for(int i = 0; i < k-1; i+=2)
                printf("%d %d\n", sum[i], sum[i+1]);
        }
    }

    return 0;
}

C. Purification

题目的意思是说,你面对一个方格,这个方格的,每一个点都需要“清洗”一下。但是有的点是可以站立的,有些点是僵尸,不能站立。你的能力是当你站在一个点上时,你可以“清洗”你所在的行和列。现在给你当前方格的状态,求出最小的站立点数,使得所有的点都能被“清洗”掉。

就是把每一行和每一列“覆盖”一下啊。站就行了。从行开始检测,如果每一行都可以站立,那就OK了。不能的话就在从列开始检测,如果可以就OK,还是不行的话就输出“-1”就可以了。最少的步数不是行数/列数就是-1了,OK,判断:

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
using namespace std;
char sp[200][200];
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i)
        scanf("%s", sp[i]);
    int hang = 0;
    int sum[10000];
    int k = 0;
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < n; ++j)
        {
            if(sp[i][j] == '.')
            {
                //cout << i << ' ' << j <<endl;
                hang++;
                sum[k++] = i+1;
                sum[k++] = j+1;
                break;
            }
        }
    }
    if(hang == n)
    {
        for(int i = 0; i < k-1; i+=2)
            printf("%d %d\n", sum[i], sum[i+1]);
    }
    else
    {
        int lie = 0;
        k = 0;
        for(int i = 0; i < n; ++i)
        {
            for(int j = 0; j < n; ++j)
            {
                if(sp[j][i] == '.')
                {
                    //cout << i << ' ' << j <<endl;
                    lie++;
                    sum[k++] = j+1;
                    sum[k++] = i+1;
                    break;
                }
            }
        }
        if(lie < n)
            printf("-1\n");
        else
        {
            for(int i = 0; i < k-1; i+=2)
                printf("%d %d\n", sum[i], sum[i+1]);
        }
    }

    return 0;
}

D. Biridian Forest

题目的意思就是打怪,你站在S点,要前往E点,但是森林中存在怪物,他们也会移动,并且移动的速度和你的一样。你如果到达一个点,这个点也有怪物的话,那你就需要大战怪兽,大战的次数等于怪物的数量。问你最少的大战次数是多少。

由于要求最优路径,肯定要用到BFS,再者,我们需要考虑如何计算我们会不会和怪兽碰上。按照题目意思,只要我们到出口的距离大于怪兽的点到出口的距离,那么我们就会碰到怪兽,这样的话,就直接可以从出口开始,求出各个点到出口的最短距离,再把怪兽的距离和我们的S的距离进行比较,如果小于的话那就不可避免的大战了,额,好吧。就是这样了:

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
using namespace std;
char sp[1500][1500];
struct node
{
    int x;
    int y;
} st,ed;
int vis[1500][1500];
int n, m;
int dx[4] = {0, 0, -1, 1};
int dy[5] = {-1, 1, 0, 0};
bool inmap(node a)
{
    if(a.x <0||a.x >= n || a.y<0 || a.y >=m)
        return false;
    return true;
}

void BFS()
{
    memset(vis, -1, sizeof(vis));
    queue<node>Q;
    vis[ed.x][ed.y] = 0;
    Q.push(ed);
    node next;
    while(!Q.empty())
    {
        node tp = Q.front();
        Q.pop();
        for(int i = 0; i < 4; ++i)
        {
            next.x = tp.x+dx[i];
            next.y = tp.y+dy[i];
            if(inmap(next) && vis[next.x][next.y]==-1&&sp[next.x][next.y]!='T')
            {
                vis[next.x][next.y] = vis[tp.x][tp.y]+1;
                Q.push(next);
            }
        }
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; ++i)
        scanf("%s", sp[i]);
    int flag = 0;
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            if(sp[i][j] == 'S')
            {
                st.x = i;
                st.y = j;
                if(flag == 1)
                {
                    i = n;
                    j = m;
                }
                else
                    flag = 1;
            }
            if(sp[i][j] == 'E')
            {
                ed.x = i;
                ed.y = j;
                if(flag == 1)
                {
                    i = n;
                    j = m;
                }
                else
                    flag = 1;
            }
        }
    }
    BFS();
    int cnt = 0;
    int MAX = vis[st.x][st.y];
    for(int i = 0; i <n ; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            if(sp[i][j]>='1'&& sp[i][j]<='9')
                if(vis[i][j] <= MAX && vis[i][j] != -1)
                    cnt+=(sp[i][j] - '0');
        }
    }
    cout << cnt <<endl;
    return 0;
}

E题,还在看...

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: #include <stdio.h> int main(){ //定义一个3*3的数组用来存储棋盘 int board[3][3]={0}; int x,y,turn=1; while (1){ //打印棋盘 printf("当前棋盘:\n"); for (x=0;x<3;x++){ for (y=0;y<3;y++){ printf("%d ",board[x][y]); } printf("\n"); } //根据turn的值来判断谁轮到落子 if (turn==1){ printf("轮到X落子,请输入落子的位置(x y):"); }else { printf("轮到O落子,请输入落子的位置(x y):"); } scanf("%d %d",&x,&y); //将落子位置的值设置为对应的值 board[x][y] = turn; //改变轮到谁落子 turn = -turn; //判断谁赢了 if (board[0][0]==board[1][1] && board[1][1]==board[2][2] && board[2][2]!=0){ printf("游戏结束,获胜者是%c\n",board[0][0]==1?'X':'O'); break; } if (board[2][0]==board[1][1] && board[1][1]==board[0][2] && board[0][2]!=0){ printf("游戏结束,获胜者是%c\n",board[2][0]==1?'X':'O'); break; } for (x=0;x<3;x++){ if (board[x][0]==board[x][1] && board[x][1]==board[x][2] && board[x][2]!=0){ printf("游戏结束,获胜者是%c\n", board[x][0] == 1 ? 'X' : 'O'); break; } if (board[0][x]==board[1][x] && board[1][x]==board[2][x] && board[2][x]!=0){ printf("游戏结束,获胜者是%c\n", board[0][x] == 1 ? 'X' : 'O'); break; } } } return 0; } ### 回答2: 为了回答这个问题,需要提供题目的具体要求和规则。由于提供的信息不够具体,无法为您提供准确的代码。但是,我可以给您一个简单的Tic-tac-toe游戏的示例代码,供您参考: ```c #include <stdio.h> #include <stdbool.h> // 判断游戏是否结束 bool isGameOver(char board[][3]) { // 判断每行是否有3个相同的棋子 for(int i = 0; i < 3; i++) { if(board[i][0] != '.' && board[i][0] == board[i][1] && board[i][0] == board[i][2]) { return true; } } // 判断每列是否有3个相同的棋子 for(int i = 0; i < 3; i++) { if(board[0][i] != '.' && board[0][i] == board[1][i] && board[0][i] == board[2][i]) { return true; } } // 判断对角线是否有3个相同的棋子 if(board[0][0] != '.' && board[0][0] == board[1][1] && board[0][0] == board[2][2]) { return true; } if(board[0][2] != '.' && board[0][2] == board[1][1] && board[0][2] == board[2][0]) { return true; } return false; } // 输出棋盘 void printBoard(char board[][3]) { for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { printf("%c ", board[i][j]); } printf("\n"); } } int main() { char board[3][3]; // 初始化棋盘 for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { board[i][j] = '.'; } } int player = 1; // 玩家1先下 int row, col; while(true) { printf("Player %d's turn:\n", player); printf("Row: "); scanf("%d", &row); printf("Column: "); scanf("%d", &col); // 判断输入是否合法 if(row < 0 || row >= 3 || col < 0 || col >= 3 || board[row][col] != '.') { printf("Invalid move. Try again.\n"); continue; } // 下棋 board[row][col] = (player == 1) ? 'X' : 'O'; // 输出棋盘 printBoard(board); // 判断游戏是否结束 if(isGameOver(board)) { printf("Player %d wins!\n", player); break; } // 切换玩家 player = (player == 1) ? 2 : 1; } return 0; } ``` 这段代码实现了一个简单的命令行下的Tic-tac-toe游戏。玩家1使用'X'棋子,玩家2使用'O'棋子。玩家依次输入行和列,下棋后更新棋盘,并判断游戏是否结束。当游戏结束时,会输出获胜者并结束游戏。 ### 回答3: 题目要求实现一个井字棋游戏的判断胜负函数。给定一个3x3的井字棋棋盘,用C语言编写一个函数,判断当前是否存在某个玩家获胜或者平局。 题目要求代码中定义一个3x3的字符数组board来表示棋盘,其中 'X' 表示玩家1在该位置放置了一个棋子, 'O' 表示玩家2在该位置放置了一个棋子, '.' 表示该位置没有棋子。 下面是实现此题的C语言代码: ```c #include <stdio.h> #include <stdbool.h> // 用于使用bool类型 bool checkWin(char board[3][3]) { // 检查每一行是否有获胜的情况 for (int row = 0; row < 3; row++) { if (board[row][0] == board[row][1] && board[row][1] == board[row][2] && board[row][0] != '.') { return true; } } // 检查每一列是否有获胜的情况 for (int col = 0; col < 3; col++) { if (board[0][col] == board[1][col] && board[1][col] == board[2][col] && board[0][col] != '.') { return true; } } // 检查对角线是否有获胜的情况 if ((board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != '.') || (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != '.')) { return true; } return false; // 没有获胜的情况 } int main() { char board[3][3]; // 存储棋盘状态 // 读取棋盘状态 for (int i = 0; i < 3; i++) { scanf("%s", board[i]); } // 调用检查胜负的函数,并输出结果 if (checkWin(board)) { printf("YES\n"); } else { printf("NO\n"); } return 0; } ``` 这个程序中定义了一个函数checkWin,用于检查是否有玩家获胜。遍历棋盘的每一行、每一列和对角线,判断是否有连续相同的字符且不为'.',如果有,则返回true;否则返回false。 在主函数main中,首先定义一个3x3的字符数组board,然后通过循环从标准输入中读取棋盘状态。接着调用checkWin函数进行胜负判断,并根据结果输出"YES"或者"NO"。最后返回0表示程序正常结束。 请注意,该代码只包含了检查胜负的功能,并没有包含其他如用户输入、判断平局等功能。如果需要完整的游戏代码,请告知具体要求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值