C. Mark and His Unfinished Essay
https://codeforces.com/contest/1705/problem/C
会卡long long,下面解法62ms过的,还是参考了dalao们的思路,发现这个思路是最最最清晰的;
学会一种新的定义long long 的方法:定义#define int long long 然后signed main()
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100
#define int long long
#define FA ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
int n,m,c,q;
int l[N],r[N],lc[N],rc[N];
//l[],r[] is 复制的区间
//lc[],rc[] is 复制完的新位置
signed main()
{
int t;
FA;
cin>>t;
while(t--)
{
cin>>n>>c>>q;
string s;
cin>>s;
int len=s.size();
for(int i=1;i<=c;i++)
{//第i次的复制区间,总共C次复制,c个区间
cin>>l[i]>>r[i];
int newlen=r[i]-l[i]+1;
//更新复制到的区间位置
lc[i]=len+1;//在现在尾位置后面粘贴
rc[i]=lc[i]+newlen-1;
len+=newlen;//更新现在的串长度
}
while(q--)
{
int k;
cin>>k;
//回去找原位置的字符
//从最后一个区间开始向前找
for(int i=c;i>=1;i--)
{//现在看看k是在哪个区间里,用该区间的l[],r[],lc[],rc[]算原位置
if(lc[i]<=k && k<=rc[i])
{
k=k-lc[i]+l[i];
//k-lc[该区间]==k数在该区间的位序
//l[i]为现在这个区间对于原区列的首位置
//加上l[i]就是该数字在原区间的序号。
}
}
cout<<s[k-1]<<endl;
}
}
return 0;
}
D. Mark and Lightbulbs
https://codeforces.com/contest/1705/problem/D
#include<stdio.h>
#include<iostream>
#include<algorithm>
#define ll long long
#include<vector>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
string a,b;
cin>>a>>b;
vector<ll> aa,bb;//存下a,b序列中的连续的块
if(a[0]==b[0] && a[n-1]==b[n-1])
{
for(int i=0;i<n-1;i++)
{
if(a[i]!=a[i+1])//计算连续的块
aa.push_back(i);
if(b[i]!=b[i+1])
bb.push_back(i);
}
if(aa.size()==bb.size())//看连续的块相同否
{
int num=aa.size();
ll cnt=0;
for(int i=0;i<num;i++)
{
cnt+=abs(aa[i]-bb[i]);//a中1移动到b相应位置的距离
}
cout<<cnt<<endl;
}
else//不相同则永远没有办法变成一样
cout<<"-1"<<endl;
}
else
{
cout<<"-1"<<endl;
}
}
return 0;
}