A. Two Rabbitsnode
思路:ios
很明顯,若是(y-x)%(a+b)==0的話ans=(y-x)/(a+b),不然就爲-1
c++
#include<iostream> #include<algorithm> using namespace std; const int maxn = 100000+5; int main(){ int k; scanf("%d",&k); while(k--){ long long x,y,a,b,ans; cin>>x>>y>>a>>b; if((y-x)%(a+b)) ans=-1; else ans=(y-x)/(a+b); cout<<ans<<endl; } }
B. Longest Palindromeide
思路:spa
直接暴力找對於每一個串的反串(也就是對於每一個i都有a[i]==a[n-i-1]),而後接着再前面沒有被找到過的串中找一個自身也是迴文串的串放在答案串的中間便可code
寫的稍稍有一些麻煩blog
#include<iostream> #include<algorithm> #include<vector> #include<cstring> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn=105; string s[maxn]; int flag[maxn]; string ans="",temp=""; int main() { int n,m,cnt=0,x,y; cin>>n>>m; for(int i=1;i<=n;i++) cin>>s[i],flag[i]=0; for(int i=1;i<=n;i++){ if(flag[i]) continue; for(int j=i+1;j<=n;j++){ y=0; for(int k=0;k<m;k++){ if(s[i][k]!=s[j][m-k-1]){ y=1; break; } } if(!y){ ans+=s[i]; flag[j]=1; flag[i]=1; cnt+=2; break; } } if(!y) continue; } for(int i=1;i<=n;i++){ if(flag[i]) continue; int x=0; for(int j=0;j<m/2;j++){ if(s[i][j]!=s[i][m-j-1]){ x=1; break; } } if(!x){ temp+=s[i]; cnt++; flag[i]=1; break; } } if(cnt==0){ cout<<"0"<<endl<<endl; return 0; } cout<<cnt*m<<endl; cout<<ans<<temp; for(int i=ans.size()-1;i>=0;i--) cout<<ans[i]; return 0; }
C. Air Conditioner排序
思路:ci
先對顧客到店的時間進行排序,以後對於每個顧客判斷[Li , Ri] 與 [LI - t ,Ri + t] 是否有交集便可get
#include <bits/stdc++.h> #define maxn 1000010 using namespace std; #define ll long long struct node{ ll t,l,h; }costomer[110]; int main() { int t; scanf("%d",&t); while(t--){ int n; ll m; scanf("%d%lld",&n,&m); ll mi=m,ma=m,tmp=0; int kk=0; for (int i = 0; i <n ; ++i) { cin>>costomer[i].t>>costomer[i].l>>costomer[i].h; mi-=(costomer[i].t-tmp); ma+=(costomer[i].t-tmp); if(ma<costomer[i].l||mi>costomer[i].h){kk=1;} else { mi=max(mi,costomer[i].l); ma=min(ma,costomer[i].h); tmp=costomer[i].t; } } if(kk)cout<<"NO"<<endl; else cout<<"YES"<<endl; } return 0; }
D. Shortest and Longest LIS
思路:
直接貪心便可,最短序列的話,對於一串大於號,咱們把當前未使用過的數儘量的放在左邊
最長序列就是反過來,儘量的放未使用過的小的數便可
#include<iostream> #include<algorithm> #include<cstring> using namespace std; const int maxn=2e5+10; int ans[maxn]; int main() { int t,n; cin>>t; string s; while(t--){ cin>>n>>s; int num=n,las=0; for(int i=0;i<n;i++){ if(s[i]=='>'||i==n-1){ for(int j=i;j>=las;j--) ans[j]=num--; las=i+1; } } for(int i=0;i<n;i++) printf("%d ",ans[i]); cout<<endl; num=1,las=0; for(int i=0;i<n;i++){ if(s[i]=='<'||i==n-1){ for(int j=i;j>=las;j--) ans[j]=num++; las=i+1; } } for(int i=0;i<n;i++) printf("%d ",ans[i]); cout<<endl; } return 0; }
E. 1-Trees and Queries
思路:
只要找到,a到b的最短路徑跟k的關係就行了
這個關係就是:只要最短路徑長度小於K,而且奇偶性跟K相同便可
證實的話很簡單:若是走到終點還沒到路徑長度還沒到k的話,就能夠不停的往回走一次,再走向終點,這樣路程的長度就爲dis+2i,要想最後能回到終點很明顯x要與k同奇偶
最短只須要經過求兩點的LCA就能夠求出,固然新加進來的一條邊會對路徑產生影響
可是咱們只要再判斷dis(a,x)+dis(b,y)+1 與 dis(a,y)+dis(b,x)+1 便可
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #define maxn 100005 using namespace std; struct edge{ int next,v; }edges[maxn*2]; int head[maxn],cnt,dep[maxn],f[maxn][21],n,q; void init() { memset(head,-1,sizeof(head)); cnt=0; } void addedge(int u,int v) { edges[cnt].next=head[u]; edges[cnt].v=v; head[u]=cnt++; } void dfs(int u,int fa) { dep[u]=dep[fa]+1; for(int i=0;i<=19;i++) f[u][i+1]=f[f[u][i]][i]; for(int i=head[u];i!=-1;i=edges[i].next) { int v=edges[i].v; if(v==fa) continue; f[v][0]=u; dfs(v,u); } } int lca(int x,int y) { if(dep[x]<dep[y]) swap(x,y); for(int i=20;i>=0;i--) { if(dep[f[x][i]]>=dep[y]) x=f[x][i]; if(x==y) return x; } for(int i=20;i>=0;i--) { if(f[x][i]!=f[y][i]) { x=f[x][i]; y=f[y][i]; } } return f[x][0]; } int getdis(int a,int b){return dep[a]+dep[b]-2*dep[lca(a,b)];} int main() { scanf("%d",&n); init(); int u,v,q,a,b,x,y,k; for(int i=1;i<n;i++){ scanf("%d%d",&u,&v); addedge(u,v),addedge(v,u); } dfs(1,0); scanf("%d",&q); while(q--){ int flag=0; scanf("%d%d%d%d%d",&x,&y,&a,&b,&k); int len1=getdis(a,b),len2=getdis(a,x)+getdis(b,y)+1,len3=getdis(a,y)+getdis(b,x)+1; if(len1<=k&&(k-len1)%2==0) flag=1; if(len2<=k&&(k-len2)%2==0) flag=1; if(len3<=k&&(k-len2)%2==0) flag=1; if(flag) cout<<"YES"<<endl; else cout<<"NO"<<endl; } }