赛后总结
这场第二题一个细节卡成傻逼,其他题的思路都挺顺的
A
签到
B
模拟,但需要注意人类先打,也就是可以赚一下就好
C
签到
D. Almost Difference
题意
给一个数组和一个分段函数,问你对于数组说有有序数对(i,j)( i <= j ) ,在分段函数下的和
思路
fst了,此题爆了long long(9*1e18),可以考虑用long double存储,输出用%Lf,但需要在C++14下才可以
考虑每个数对答案的贡献,即被当做x和y的次数,然后再处理一下特殊的情况即可
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=2e5+5; unordered_map<ll,ll>sum; ll n; ll a[N]; int main() { scanf("%I64d", &n); long double summ=0; for(int i=1;i<=n;i++) { scanf("%I64d",&a[i]); summ-=(n-i)*a[i]; summ+=(i-1)*a[i]; } for(int i=1;i<=n;i++) { sum[a[i]]++; summ-=(sum[a[i]-1]); summ+=sum[a[i]+1]; } printf("%.0Lf ", summ); return 0; }
E. Swapping Characters
题意
给k个长度为n的字符串,问是否存在一个字符串,使得这k个字符串是通过这个字符串交换位置不相同的两个字符而来
分析
优美暴力
直接枚举第一个串的所有情况,考虑一开始与第一个串不同的位置, 然后考虑交换第一个字符串的任意两个字符,看看是否可以与其他所有匹配,
需要注意的是,要考虑一下,换的位置是不是一开始相同的位置,分情况讨论一下即可
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+10; vector<int> dif[maxn]; char s[2500][5000+1]; int cnt[5000+5][30]; int main() { int n,k; scanf("%d%d", &k, &n); int f=0; for(int i=1;i<=k;i++) { scanf("%s", s[i]); int k=0; for(int j=0;j<n;j++) { cnt[i][s[i][j]-'a']++; if(s[i][j]!=s[1][j]) k++,dif[i].push_back(j); } if(k>4) return 0*puts("-1"); for(int j=0;j<26;j++) { if(cnt[1][j]!=cnt[i][j]) return 0*puts("-1"); if(cnt[1][j]>1) f=1; } } for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { swap(s[1][i], s[1][j]); int flag=1; for(int t=2;t<=k;t++) { int num=0; int ans1=0, ans2=0; for(int id=0;id<int(dif[t].size());id++) { if(i==dif[t][id]) ans1=1; if(j==dif[t][id]) ans2=1; if(s[1][dif[t][id]]!=s[t][dif[t][id]]) num++; } if(!ans1) if(s[1][i]!=s[t][i]) num++; if(!ans2) if(s[1][j]!=s[t][j]) num++; if(num>2) { flag=0; break; } if(num==0 && f==0) { flag=0; break; } } if(flag) { printf("%s ", s[1]); return 0; } else { swap(s[1][i],s[1][j]); } } } return 0*puts("-1"); }