A.Three Friends(枚举)
思路:输入之后排序,然后枚举所有的情况
- a a b
a+1看一下是不是b-a+b-a+a-a是不是等于0,等于0就输出不等于0就输出b-a+b-a+a-a-2; - a b b
b-1看一下是不是b-a+b-a+b-b是不是等于0,等于0就输出不等于0就输出b-a+b-a+b-b-2; - a b c
b不动 a+1,c-1 输出c-b+c-a+b-a
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main (){
int q;
long long ans1;
vector<long long>v(3);
cin>>q;
while(q--){
ans1=0;
cin>>v[0]>>v[1]>>v[2];
sort(v.begin(),v.end());
if(v[2]==v[1]&&v[1]==v[0]){
ans1 = 0;
cout<<ans1<<endl;
continue;
}
if(v[2]==v[1]&&v[1]>v[0]){
v[2]--;
v[1]--;
ans1 = v[2]-v[1]+v[1]-v[0]+v[2]-v[0];
if(ans1==0){
cout<<ans1<<endl;
continue;
}
ans1-=2;
cout<<ans1<<endl;
continue;
}
if(v[0]==v[1]&&v[1]<v[2]){
v[0]++;
v[1]++;
ans1 = v[2]-v[1]+v[1]-v[0]+v[2]-v[0];
if(ans1==0){
cout<<ans1<<endl;
continue;
}
ans1-=2;
cout<<ans1<<endl;
continue;
}
if(v[2]>v[1]){
v[2]--;
}
if(v[1]>v[0]){
v[0]++;
}
ans1 = v[2]-v[1]+v[1]-v[0]+v[2]-v[0];
cout<<ans1<<endl;
}
}
B.Snow Walking Robot(枚举)
思路:统计串中四个字符的出现次数的u,d,r.l,一个点不走两次,必然有r=l=min(l,r),u=d=min(d,u),
- l=0&&u==0 输出0
- l=0&&u!=0 输出2
- l!=0&&u=0 输出2
- 输出 2l+2r 按照矩形输出要求的指令
#include<iostream>
#include<map>
using namespace std;
string s;
int t;
map<char,int>mp;
int main (){
cin>>t;
while(t--){
cin>>s;
mp.clear();
int len = s.size();
for(int i = 0 ; i < len;i++)
mp[s[i]]++;
int ans = 0;
int l = min(mp['R'],mp['L']);
int u = min(mp['U'],mp['D']);
mp['R'] = l;
mp['L'] = l;
mp['U'] = u;
mp['D'] = u;
if(l==0&&u==0){
cout<<0<<endl;
continue;
}
if(l==0){
cout<<2<<endl;
cout<<"UD"<<endl;
continue;
}
if(u==0){
cout<<2<<endl;
cout<<"LR"<<endl;
continue;
}
cout<<(l+u)*2<<endl;
while(mp['R']>0){
cout<<'R';
mp['R']--;
}
while(mp['U']>0){
cout<<'U';
mp['U']--;
}
while(mp['L']>0){
cout<<'L';
mp['L']--;
}
while(mp['D']>0){
cout<<'D';
mp['D']--;
}
cout<<endl;
}
}
C.Yet Another Broken Keyboard
思路:坏的键会分割出来的各个好的串,然后做法就变成了题目一开始说的在好的串里挑选字串的公式 l*(l+1)/2
会爆int 所以res必须用long long
#include<iostream>
#include<string>
#include<map>
using namespace std;
int n,k;
string s;
map<char,int>mp;
int main (){
cin>>n>>k;
cin>>s;
int len = s.size();
char c;
for(int i = 0 ; i < k ;i++){
cin>>c;
mp[c]=1;
}
long long l=0;
long long res = 0;
int flag=0;
for(int i = 0 ; i< len;i++){
if(mp[s[i]]==1){
flag = 0;
l=0;
while(i<len&&mp[s[i]]==1){
i++;
l++;
if(mp[s[i]]!=1){
flag=1;
break;
}
}
if(flag||i==len){
res += (1+l)*l/2;
flag=0;
}
}
}
cout<<res<<endl;
}
D.Remove One Element
思路:dp[i][j]表示到第i位置的时候有删除过j个元素, j取0,1
-
a[i]>a[i-1]
dp[i][0]=max(dp[i][0],dp[i-1][0]+1)
dp[i][1]=max(dp[i][1],dp[i-1][1]+1) -
a[i]>a[i-2]
dp[i][1]=max(dp[i][1],dp[i-2][0]+1)
#include <cstdio>
#include <algorithm>
#include<iostream>
using namespace std;
const int maxn = 2e5 + 5;
int n,a[maxn];
int dp[maxn][2], ans;
int main() {
std::ios::sync_with_stdio(false);
cin>>n;
for (int i = 1; i <= n; i++)
cin>>a[i];
dp[1][0] = 1;
for (int i = 2; i <= n; i++) {
dp[i][0] = dp[i][1] = 1;
if (a[i] > a[i - 1]) {
dp[i][0] = max(dp[i][0], dp[i - 1][0] + 1);
dp[i][1] = max(dp[i][1], dp[i - 1][1] + 1);
}
if (a[i] > a[i - 2]) {
dp[i][1] = max(dp[i][1], dp[i - 2][0] + 1);
}
ans = max(ans, max(dp[i][0], dp[i][1]));
}
cout<<ans;
return 0;
}
E.Nearest Opposite Parity
看了之后显然要建图,求所有点的最短路径,但是在求得过程中,很明显每个点都求一遍超时,例如给你2*10个2,比赛结束想了一下只要建立2个超级源点:代替所有的偶数点,代替所有的奇数点。这样只要求两遍最短路就可以了。假如现在跑完了奇数的超级源点,显然所有的偶数点的答案就是与超级源点最近距离。详情看代码。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const long long inf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 2e6+100;
bool vis[maxn];
int head[maxn];
long long res[maxn];
long long dis[maxn];
struct node{
int v,nex,d;
}node[maxn];
int n,tot;
int a[maxn];
void init(){
for(int i=1;i<=2+n;i++){
dis[i]=inf;
vis[i]=false;
}
}
void addedge(int u,int v,int d){
node[++tot].v = v;
node[tot].nex = head[u];
node[tot].d = d;
head[u]=tot;
}
void spfa(int u){
queue<int>q;
q.push(u);
vis[u]=true;
dis[u]=0;
while(!q.empty()){
u = q.front();
q.pop();
vis[u]=false;
for(int i=head[u];~i;i=node[i].nex){
int v = node[i].v;
if(dis[v]>dis[u]+node[i].d){
dis[v]=dis[u]+node[i].d;
if(!vis[v]){
q.push(v);
vis[v]=true;
}
}
}
}
}
int main(){
std::ios::sync_with_stdio(false);
cin>>n;
memset(head,-1,sizeof(head));
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]+i<=n) addedge(a[i]+i,i,1);
if(i-a[i]>=1) addedge(i-a[i],i,1);
}
for(int i=1;i<=n;i++){
if(a[i]%2) addedge(n+1,i,0);
if(a[i]%2==0) addedge(n+2,i,0);
}
init();
spfa(n+1);
for(int i=1;i<=n;i++)
if(a[i]%2==0) res[i] = dis[i];
init();
spfa(n+2);
for(int i=1;i<=n;i++)
if(a[i]%2) res[i] = dis[i];
for(int i=1;i<=n;i++){
if(res[i]==inf){
cout<<-1<<" ";
}
else {
cout<<res[i]<<" ";
}
}
}
*终究是菜鸡,做的时候第二题都能错三遍- - **