Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) ABCDE总结

比赛的时候过了四题,终测完就剩俩题。。。继续掉分。。。

A:给你两个字符串s,t,s中至多包含一个*,*可以为空串,问你能否将*用一个串替换后,s变成t。有*的话,直接分别从左从右判就好了,但是没有的话,需要特判,两个串一样就yes,否则no。绝大多数挂终测的人都没考虑没*的情况(包括我)

B:给你n表示n件物品价值分别为1~n,求从中任选两件价值和为m的放法总数。直接上一段神奇的代码:

#include <bits/stdc++.h>
using namespace std;
long long n, m;
int main() {
	cin >> n >> m;
	if (n >= m)
		n = m - 1;
	long long mn = m - n;
	long long ans = (m / 2 - mn + 1);
	if (m % 2 == 0)
		ans --;
	cout << (ans > 0 ? ans : 0);
	return 0;
}

是不是很简单?(可惜不是我写的)然而我还是挂了终测,这是大神通过的代码

C:给你一个长度为n的括号序列,让你输出一个长度为m的合法序列,这个合法序列由第一个串删除若干个字符而来。

只需要扫一遍,记录右边有多少个右括号,已经输出了几个左括号,再输出一个左括号剩下的数量够不够输出右括号即可。

D:给你一个包含n个数的序列,0表示未知,q次修改,第i次修改将区间[l,r]的数变成i。给你答案序列,问你能否还原这个序列。

其实不能还原只有两种情况。

1、出现了6 5 6这样中间比两边小且两边数相同的情况。

2、原序列没有0并且没有q。因为q是最后一次修改,所以答案序列中必须有q才行。

然后用树状数组判第一种情况,第二种情况特判即可。最后能还原的话,如果序列中没有q先补一个q。然后剩下的0用靠近它的不为0的数补就行了。

E:(又是坑爹的互动题)n*n的格子,从(1,1)走到(n,n),每次只能向右或者向下走一格。格子中有障碍物位置,每次查询只会告诉你是否能从(a,b)走到(c,d),是就yes,否则no。其实就是模拟,用a[i][j]表示i是否能走到j。然后从(1,1)走到(n,n)模拟查询一次,再从(n,n)走向(1,1)模拟查询一次。(注意优先走的方向要一致),最后从(1,1)开始根据a[i][j]查找一条路径即可。互动题还是做得太少了,以后还要继续加强训练。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=510;
int n,m,k;
int a[maxn][maxn];
int c[maxn];
int ans,ct,cnt,tmp,flag;
char s[maxn];
bool jud(int r1,int c1,int r2,int c2){
	printf("? %d %d %d %d\n",r1,c1,r2,c2);
	string s;
	cin>>s;
	fflush(stdout);
	return s=="YES";
}
int main()
{
    scanf("%d",&n);
    int x=1,y=1;
    a[x][y]=a[n][n]=jud(x,y,n,n);
    for(int i=0;i<n-1;i++)
    if(jud(x,y+1,n,n)) a[x][++y]=1;
    else a[++x][y]=1;
    x=n,y=n;
    for(int i=0;i<n-1;i++)
    if(jud(1,1,x-1,y)) a[--x][y]=1;
    else a[x][--y]=1;
    string ans;
    x=1,y=1;
    while(x+y!=2*n)
    if(a[x][y+1]) {ans+="R";y++;}
    else {ans+="D";x++;}
    printf("! %s\n",ans.c_str());
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LSD20164388/article/details/81805646