D题
每个字符串用map存一下;
然后遍历每个字符串,前i个字符和后面的字符是否都已经存在,如果都存在,则可以构成
#include<bits/stdc++.h>
using namespace std;
string s[100005];
void solve()
{
int n;
cin>>n;
map<string,int>mp;
for(int i=1;i<=n;i++){
cin>>s[i];
mp[s[i]]++;
}
for(int i=1;i<=n;i++){
bool ok=false;
string l;
for(int j=0;j<s[i].length();j++){
l+=s[i][j];
string r;
for(int k=j+1;k<s[i].length();k++){
r+=s[i][k];
}
if(mp[l]&&mp[r]){
ok=true;
break;
}
}
if(ok)cout<<"1";
else cout<<"0";
}
cout<<"\n";
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
}
E题
先找出来i,j点对应的4个旋转点,然后查看这4个点是1还是0,每次答案加上步数最少的步数,然后把它们统一换成1(0同理一样);
#include<bits/stdc++.h>
using namespace std;
char s[105][105];
void solve()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>s[i]+1;
int res=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
int yi=0;
if(s[i][j]=='1')yi++;
if(s[j][n-i+1]=='1')yi++;
if(s[n-j+1][i]=='1')yi++;
if(s[n-i+1][n-j+1]=='1')yi++;
res+=min(yi,4-yi);
s[i][j]='1';
s[j][n-i+1]='1';
s[n-i+1][n-j+1]='1';
s[n-j+1][i]='1';
}
cout<<res<<"\n";
}
int main()
{
int t;
cin>>t;
while(t--)
{
solve();
}
}
F题
首先用树状数组把所有a[i]<i的点都存起来,存的时候存取的是a[i];
之后再遍历一下,每次遇到a[i]<i的点,就搜索一下有多少个a[j]>i>a[i];(由于a[j]被存的条件,所以a[j]一定小于j)
每次遍历时要去掉本身点
#include<bits/stdc++.h>
using namespace std;
int a[200005];
int tr[200005];
int lowbit(int x){
return x&-x;
}
void add(int x,int v){
if(!x)return;
for(int i=x;i<=200002;i+=lowbit(i))tr[i]+=v;
}
int query(int x){
int res=0;
for(int i=x;i>0;i-=lowbit(i))res+=tr[i];
return res;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
if(a[i]<i){
add(a[i],1);
}
}
long long sum=0;
for(int i=1;i<=n;i++){
if(a[i]<i)
{
add(a[i],-1);
sum+=query(200000)-query(i);
}
}
cout<<sum<<"\n";
}
}