【题目记录】——Codeforces Round #744 (Div. 3)


题目集地址 Codeforces Round #744 (Div. 3)

A Casimir’s String Solitaire 简单题+字符串

题目地址A Casimir’s String Solitaire
题目大意:给一个字符串只含有A,B,C,然后每次操作删除一个B和C或者是一个B和A,问最后能不能将字符串变为空串,能输出yes,否则输出no
思路:就是统计整个字符串的长度,然后再统计B的个数,只需要满足B的个数等于剩下的字符的个数即可。
AC代码:

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
string str;
void solve()
{
	cin >> str;
	int b=0;
	for(int i = 0;i < str.size();i++)
    {
        if(str[i]=='B')
        {
            b++;
        }
    }
    if(str.size()==2*b)
    {
        printf("YES\n");
    }
    else
    {
        printf("NO\n");
    }
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

B Shifting Sort 思维+模拟

题目地址B Shifting Sort
题目大意:给定一个长度为n的序列,给定一种操作:选择区间[l,r],循环左移k位,操作次数要小于n,最后将序列排为升序,如何操作。
思路:就是模拟循环左移,如果我需要将aj移到ai的位置,那么我的操作就是i,j,j-i;然后执行一次插入排序。
AC代码:

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
struct r{
    int l,r;
}res[55];
int a[55],b[55];
void solve()
{
    int n;
    scanf("%d",&n);
    for(int i = 1;i <= n;i++)
    {
        scanf("%d",a+i);
    }
    int cnt = 0;
    for(int i = 2;i <= n;i++)
    {
        int l=0;
        if(a[i]<a[i-1])
        {
            for(int j = i;j>=2;j--)
            {
                if(a[j]>=a[j-1])
                {
                    l=j;
                    res[cnt].r=i;
                    break;
                }
                else
                {
                    swap(a[j],a[j-1]);
                }
            }
            if(l==0)
            {
                res[cnt].l=1;
            }
            else
            {
                res[cnt].l=l;
            }
            res[cnt].r=i;
            cnt++;
        }
    }
    printf("%d\n",cnt);
    for(int i = 0;i < cnt;i++)
    {
        printf("%d %d %d\n",res[i].l,res[i].r,res[i].r-res[i].l);
    }
}

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

C Ticks 思维+模拟

题目地址C Ticks
题目大意:给定一个图,一开始是空白的,一个初始坐标,i,j从ij开始给方格涂色,每一次涂两个方格(i-h,j-h),(i-h,j+h),h的范围是[0,h],h的值必须大于等于k,ij的值可以是多个,涂色的结果如图所示。
在这里插入图片描述
题目要求判断给一个涂好色的矩阵,判断能不能在满足条件的情况下将空白的图涂成给定的结果。输出yes或no。
思路:就是找顶点,找到顶点后开始向左上和右上涂色,如果h大于等于k,就用一个标记数组标记这些位置被涂色的色块可以涂上色,遍历一次找到所有的顶点后,对比标记数组和最终的矩阵对应的涂色位置是否一致,如果一致表明该图可以经过涂色涂出来。
对,思路就是这样的,但是我写的代码死活不对,关键还找不到错误用例,还是我太菜了。这是正确代码。
AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#define x first
#define y second
using namespace std;
const int MAXN = 122;
int n, m, ok;
string mp[MAXN];
int vis[MAXN][MAXN];
void cal(int i, int j)
{
	int h= 0;
	vector<pair<int, int>> ve;
	for (int r = 0; i - r >= 0 && j - h >= 0 && j + h < m; r++)
	{
		if (mp[i - r][j - h] == mp[i - r][j + h] && mp[i - r][j - h] == '*') ve.push_back({ r,h }),h++;
		else break;
	}
	for (auto it : ve) {
		int &l = vis[i - it.x][j - it.y];
		l = max(l, h - 1);
		int& r = vis[i - it.x][j + it.y];
		r = max(r, h - 1);
	}
	
}
void solve()
{
	cin >> n >> m >> ok;
	for (int i = 0; i < n; i++)cin >> mp[i];
	for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)vis[i][j] = 0;
	for(int i=n-1;i>=0;i--)
		for (int j = m - 1; j >= 0; j--)
		{
			if (mp[i][j] != '*')continue;
			cal(i, j);
			if (vis[i][j] < ok) { puts("NO"); return; }
		}
	puts("YES");
	return;
}
int main()
{
	int T; cin >> T;
	while (T--)solve();
	return 0;
}

我的错误代码:

#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=20;
bool mm[N][N];
bool vis[N][N];
void draw(int r,int c,int n,int m,int k)
{
    int i;
    for(i = 1;r-i>=1&&c-i>=1&&c+i<=m;i++)
    {
        if(!(mm[r-i][c-i]&&mm[r-i][c+i]))
        {
            break;
        }
    }
    if(i-1 >= k)
    {
        vis[r][c]=true;
        for(i = 1;r-i>=1&&c-i>=1&&c+i<=m;i++)
        {
            if(mm[r-i][c-i]&&mm[r-i][c+i])
            {
                vis[r-i][c-i]=true;
                vis[r-i][c+i]=true;
            }
        }
    }
}
void solve()
{
    int n,m,k;
    char c;
    scanf("%d%d%d",&n,&m,&k);
    for(int i = 1;i <= n;i++)
    {
        for(int j = 1;j <= m;j++)
        {
            scanf("%c",&c);
            while(c=='\n')
            {
                scanf("%c",&c);
            }
            if(c=='*')
            {
                mm[i][j]=true;
            }
        }
    }
    for(int i = k+1;i<=n;i++)
    {
        for(int j = k+1;j <= m;j++)
        {
            if(mm[i][j]&&j<=m-k)
            {
                if(mm[i-1][j-1]&&mm[i-1][j+1])
                {
                    draw(i,j,n,m,k);
                }
            }
        }
    }
    bool flag=true;
    for(int i = 1;i <= n&&flag;i++)
    {
        for(int j = 1;j <= m&&flag;j++)
        {
            if(vis[i][j]!=mm[i][j])
            {
                flag=false;
            }
        }
    }

    if(flag)
    {
        printf("YES\n");
    }
    else
    {
        printf("NO\n");
    }
    memset(mm,0,sizeof(mm));
    memset(vis,0,sizeof(vis));
}

int main()
{
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
//	int t = 1;
	int t;
	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值