7.6补题

CodeForces - 1272B
题意:起始位置原点,UDLR分别代表上下左右移动,要求最后回到原点并且不能有点经过两次,根据给出的步骤判断是否符合要求,符合可删去部分输出重拍后的走法

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define INF 0x3f3f3f3f
#define m 2008
using namespace std;
char s[100010];
int main(){
    int q;
    cin>>q;
    while(q--)
    {
        cin>>s;
        int n=strlen(s);
        int l=0,r=0,d=0,u=0;
        for(int i=0;i<n;i++)
        {
            if(s[i]=='U') u++;
            if(s[i]=='D') d++;
            if(s[i]=='L') l++;
            if(s[i]=='R') r++;
        }
        int x=min(l,r),y=min(u,d);
        if(x==0&&y==0) cout<<'0'<<endl;
        else if(x==0&&y) cout<<'2'<<endl<<"UD"<<endl;
        else if(x&&y==0) cout<<'2'<<endl<<"LR"<<endl;
        else
        {
            cout<<2*(x+y)<<endl;
            for(int i=1;i<=y;i++) cout<<'U';
            for(int i=1;i<=x;i++) cout<<'R';
            for(int i=1;i<=y;i++) cout<<'D';
            for(int i=1;i<=x;i++) cout<<'L';
            cout<<endl;
        }
    }
	return 0;
}

当时没有选做这题因为看题目过长,认为可能难度较高,实际上不是这样,上下,左右移动的步数相等,另一个题目非常有意思的一个点在于重拍后的走法不能有重叠,最简单的做法是直接围一个长方形。

CodeForces - 1272C
题意:给出一串长n的字符串s,再给出k个单独的字符,要求算出该k个字符可以构成几个s的子串(按照s的顺序,字符串可以重复)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define INF 0x3f3f3f3f
#define m 2008
using namespace std;
char x;
int a[27]={0};
string s;
int main(){
    long long n,k,lent=0;
    long long ans=0;
    cin>>n>>k;
    cin>>s;
    for(int i=1;i<=k;i++)
    {
        cin>>x;
        a[x-'a'+1]=1;
    }
    for(int i=0;i<n;i++)
    {
        if(a[s[i]-'a'+1]) lent++;
        else
        {
            ans+=(lent+1)*lent/2;
            lent=0;
        }
    }
    ans+=(lent+1)*lent/2;
    cout<<ans<<endl;
	return 0;
}

这题当时也没做出来,事后补的时候异常艰难,大致的思路是将s中每个含有k个特定字符的最长连续字符串的长度算出来,对每个的长度使用求和公式算出各个最长的子串数,最后相加,注意题目说n最大是2*10^5,结果很有可能超int,所以我第一次错在了最后的ans没有用int ,但还是不能AC,将n,k,lent也改为long long 却能过,所以我猜可能是有测试数据超了题目所给的范围,达到了long long.

CodeForces - 1272D
题意:求最长上升子序列,可以去掉一个

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define INF 0x3f3f3f3f
#define m 2008
using namespace std;
int l[200010],r[200010],a[200010];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    l[1]=1;
    for(int i=2;i<n;i++)
    {
        if(a[i]>a[i-1]) l[i]=l[i-1]+1;
        else
            l[i]=1;
    }
    r[n]=1;
    for(int i=n-1;i>1;i--)
    {
        if(a[i+1]>a[i]) r[i]=r[i+1]+1;
        else
            r[i]=1;
    }
    int maxn=1;
    if(a[1]<a[2]) maxn=l[1]+r[2];
    for(int i=3;i<=n;i++)
    {
        if(a[i]>a[i-1]) maxn=max(maxn,l[i-1]+r[i]);
        if(a[i]>a[i-2]) maxn=max(maxn,l[i-2]+r[i]);
    }
    cout<<maxn<<endl;
	return 0;
}

重要是的思路,只要想到了用LR两个数组基本上就很容易解决,但要注意所有数都相等的情况。

CodeForces - 1272E *
题意:给出一个n个数的数组a,第i个数加或减a[i]得到的数j是否还在1-n之间,看a[j]与a[i]的奇偶性是否相同,若相同,重复上述步骤,求出奇偶性不同需要该步骤的次数;不能达到该目的即j不在1-n时输出-1,表示不能。
7.6补题_第1张图片
反向建图,还没搞懂

CodeForces - 1272F *
题意:输入两个括号序列,输出一个序列,使得满足的条件的括号序列都是它的子序列
7.6补题_第2张图片
7.6补题_第3张图片dp[i][j][k]表示匹配到的s的第I个,t的第j个,s的第I个

你可能感兴趣的:(7.6补题)