我叼,打的時候CF被ddos了,還有這種操做?害得我只能睡覺html
最後一題留坑ios
A. Prime Subtractionc++
覺得是求GCD,上去wa一發。。。後來發現,y-x=C,若是C不爲1,那麼確定能夠由素數組成,偶數直接+2,奇數就是3+2*k ,k>=0數組
#include<bits/stdc++.h> #define LL long long #define pii pair<int,int> #define pb push_back #define mp make_pair using namespace std; int main(){ int t; LL a,b; scanf("%d",&t); while(t--){ scanf("%lld%lld",&a,&b); if (a-b==1){ printf("NO\n"); }else { printf("YES\n"); } } return 0; }
B 先打遠的,每次打完,判斷一下是否有被震到x<0的,直接模擬便可ide
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> using namespace std; const int maxx = 2e5+6; int a[maxx]; vector<int>v; bool cmp(int x,int y){ return x<y; } int main(){ int q; int n; long long rr; scanf("%d",&q); while(q--){ v.clear(); scanf("%d%lld",&n,&rr); for (int i=1;i<=n;i++){ scanf("%d",&a[i]); v.push_back(a[i]); } sort(v.begin(),v.end(),cmp); v.erase(unique(v.begin(),v.end()),v.end()); int l=0,r=v.size()-1; long long step=0; int ans=0; while(l<=r){ ans++; r--; step+=rr; while(l<=r && v[l]-step<=0){ l++; } } printf("%d\n",ans); } return 0; }
C. Standard Free2playui
咱們發現只要兩個數間隔差>=2好比5-3,你必定能夠先到4;100-1你必定能夠先到2,而後咱們判斷若是當前和下一個是連續的,也就是說3-2,那麼你能夠先到4,而後3的狀態改變,而後到2,不然就不行,咱們spa
就必須用一個魔法值,前面說了a[i+1]-a[i]>1那麼你能夠直接改變當前i的狀態,而後走到a[i+1]+1的狀態。最後判斷一下,最後的狀態是否是高度大於2,若是是的話,咱們直接改變最後的狀態,而後就能夠到0了。3d
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> using namespace std; const int maxx = 2e5+6; int a[maxx]; int main(){ int t; int h,n; scanf("%d",&t); while(t--){ scanf("%d%d",&h,&n); for (int i=1;i<=n;i++){ scanf("%d",&a[i]); } int cnt=0; for (int i=1;i<=n;i++){ if (a[i]>=h){ continue; } if (h-a[i]>1){ h=a[i]+1; } if (i<n){ if (a[i+1]==a[i]-1){ h=a[i+1]; }else{ cnt++; h=a[i]; } continue; } if (h>2)cnt++; } printf("%d\n",cnt); } return 0; }
D 找出全部的串,每個字符都至少屬於一個迴文串,發現其實這種迴文串不少,咱們反着考慮,找不知足的,那麼只有ABBBBB,BAAAAAA,AAAAB,BBBBBA這四種類型,其餘的都是,由於字符畢竟只有兩種,code
那麼先後掃一遍便可,htm
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #define LL long long using namespace std; const int maxx= 3e5+6; char a[maxx]; int main(){ LL n; while(~scanf("%lld",&n)){ scanf("%s",&a); int len=strlen(a); LL ans=n*(n-1)/2; int pre=0; for (int i=1;i<len;i++){ if (a[i]==a[i-1])continue; ans++; ans-=(i-pre); pre=i; } pre=len-1; for (int i=len-2;i>=0;i--){ if (a[i]==a[i+1])continue; ans-=(pre-i); pre=i; } printf("%lld\n",ans); } return 0; }
E 頗有意思,咱們暫時也不怎麼懂,這個DP太秀了。。。咱們發現位數只有20位,那麼其實能夠經過枚舉已經安排的狀態來考慮。
當前狀態i表明當前i的二進制位上的英文單詞是否被安排
參考一下
http://www.javashuo.com/article/p-tynacpbm-dk.html
#include <bits/stdc++.h> #define LL long long using namespace std; const int maxx = 1e5+6; const int maxn = 2e6+7; char str[maxx]; LL dp[maxn]; LL cnt[30][30]; int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ scanf("%s",str); int len=strlen(str); for (int i=1;i<len;i++){ int x=str[i-1]-'a'; int y=str[i]-'a'; if (x!=y)cnt[x][y]++,cnt[y][x]++; } for (int i=1;i<=(1<<m);i++){ dp[i]=INT_MAX; } for (int i=0;i<(1<<m)-1;i++){ LL c=__builtin_popcount(i); for (int j=0;j<m;j++){ if(!(i&(1<<j))){ LL tmp=dp[i]; for (int k=0;k<m;k++){ if (i&(1<<k)){ tmp+=cnt[j][k]*c; }else { tmp-=cnt[j][k]*c; } } dp[i|(1<<j)]=min(dp[i|(1<<j)],tmp); } } } printf("%lld\n",dp[(1<<m)-1]); } return 0; }
F 樹上毛毛蟲
其實就是找一條鏈,與這個鏈直接相連的節點儘量的多。
其實樹形DP,就能夠,咱們維護兩個大的DP值,表明兒子節點中最大的兩個值,dp[i],表明i的子樹中鏈上所鏈接的點儘量的多。
那麼對於每一個節點,維護一個maxx,minn,表明不一樣的兒子節點中,子樹鏈上鍊接的點,最多的和次多的,而後維護一個maxx+minn+son[i]-2+1表示把兩個鏈連在一塊兒,加上當前節點的兒子節點的個數,減去因爲maxx和minn鏈上兩個點是在son裏面,再加上當前節點自己。
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #define LL long long using namespace std; const int maxx = 3e5+6; int ver[maxx*2],Next[maxx*2],head[maxx]; int n,m,tot; int dp[maxx],son[maxx]; int ans; void add(int x,int y){ ver[++tot]=y;Next[tot]=head[x];head[x]=tot; ver[++tot]=x;Next[tot]=head[y];head[y]=tot; son[x]++; son[y]++; } void dfs(int u,int fa){ dp[u]=1; int minn=0,maxx=1; for (int i=head[u];i;i=Next[i]){ int v=ver[i]; if (v==fa)continue; dfs(v,u); if (maxx<dp[v]){ minn=maxx; maxx=dp[v]; }else if (minn<dp[v]){ minn=dp[v]; } dp[u]=max(dp[u],dp[v]+son[u]-1); } ans=max(minn+maxx+son[u]-1,ans); } int main(){ int uu,vv; int t; scanf("%d",&t); while(t--){ scanf("%d",&n); ans=0; for (int i=1;i<=n;i++){ dp[i]=0; head[i]=0; son[i]=0; } for (int i=1;i<=n-1;i++){ scanf("%d%d",&uu,&vv); add(uu,vv); } dfs(1,0); printf("%d\n",ans); } return 0; }