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,表示不能。
反向建图,还没搞懂
CodeForces - 1272F *
题意:输入两个括号序列,输出一个序列,使得满足的条件的括号序列都是它的子序列
dp[i][j][k]表示匹配到的s的第I个,t的第j个,s的第I个