Solved | Pro.ID | Title | Ratio(Accepted / Submitted) |
1001 | Game On the Tree | 4.44%(2/45) | |
1002 | Tree Maker | 18.75%(21/112) | |
1003 | Hotaru's problem | 10.60%(160/1509) | |
1004 | Segment Game | 13.07%(52/398) | |
1005 | The shortest problem | 26.38%(607/2301) | |
1006 | Tetris | 30.34%(44/145) | |
1007 | Gray code | 31.25%(456/1459) | |
1008 | Convex Polygon | 18.18%(4/22) | |
1009 | Root | 3.41%(7/205) | |
1010 | Leader in Tree Land | 28.74%(50/174) | |
1011 | Mahjong tree | 19.25%(257/1335) |
Pro.ID | Title | Author | Source | (AC/Submit)Ratio |
5369 | Game On the Tree | 2015 Multi-University Training Contest 7 | (12/54)22.22% | |
5370 | Tree Maker | 2015 Multi-University Training Contest 7 | (46/118)38.98% | |
5371 | Hotaru's problem | 2015 Multi-University Training Contest 7 | (593/1653)35.87% | |
5372 | Segment Game | 2015 Multi-University Training Contest 7 | (270/965)27.98% | |
5373 | The shortest problem | 2015 Multi-University Training Contest 7 | (481/948)50.74% | |
5374 | Tetris | 2015 Multi-University Training Contest 7 | (97/217)44.70% | |
5375 | Gray code | 2015 Multi-University Training Contest 7 | (361/612)58.99% | |
5376 | Convex Polygon | 2015 Multi-University Training Contest 7 | (22/70)31.43% | |
5377 | Root | 2015 Multi-University Training Contest 7 | (31/102)30.39% | |
5378 | Leader in Tree Land | 2015 Multi-University Training Contest 7 | (133/351)37.89% | |
5379 | Mahjong tree | 2015 Multi-University Training Contest 7 | (341/1114)30.61% |
HDU5371php
給一個長度爲n的序列,求最長的連續子序列長度。符合:ios
能夠分紅3部分 ,第一部分與第三部分同樣,第一部分與第二部分互爲轉置。算法
如2 3 4 4 3 2 2 3 4 數組
用manacher算法O(n)時間算出以s[i]和s[i+1]爲中心的迴文串的半徑f[i],只要在f[i]的半徑範圍[i-f[i],i+f[i]-1]內有f[j]>|j-i|就說明存在符合要求的串,遍歷求最大值便可ide
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int s[220220]; int p[220220]; int f[220220]; int main() { int T; scanf("%d",&T); for(int ca=1;ca<=T;ca++) { int len; scanf("%d",&len); for(int i=0;i<len;i++) { s[i*2]=-1; scanf("%d",&s[i*2+1]); } len*=2; s[len]=-1; p[0]=1; p[1]=2; int maxlen=1; int id=1; for(int i=2;i<=len;i++) { if(i>maxlen) { int k=1; while(i-k>=0&&i+k<=len&&s[i-k]==s[i+k])k++; p[i]=k; maxlen=min(p[i]+i-1,len); id=i; } else { if((2*id-i)-p[2*id-i] != id-p[id]) p[i]=min(p[2*id-i],maxlen-i+1); else { int k=p[2*id-i]; while(i-k>=0&&i+k<=len&&s[i-k]==s[i+k])k++; p[i]=k; maxlen=min(p[i]+i-1,len); id=i; } } } for(int i=0;i<=len;i+=2) { f[i/2]=(p[i]-1)/2; } int ans=0; len/=2; for(int i=0;i<len;i++) { for(int j=ans+1;j<=f[i];j++) { if(f[i+j]>=j)ans=max(ans,j); } } printf("Case #%d: %d\n",ca,ans*3); } return 0; }
HDU5372spa
有一個數軸,每次往數軸上放一個線段[a,b]或者刪除一個線段(每一個線段獨立)(id),在放前詢問[a,a+i]內有多少完整的線段,即以前放的線段有多少是徹底在[a,b]的範圍內的code
[a,b]中b=a+ind,ind爲放線段的個數(不包括刪除) , id爲第id個放入的線段。blog
用兩個樹狀數組分別維護 <=a ,<=b 的個數,詢問時求出左邊大於等於當前左端點的線段數目和右邊大於當前右端點線段數目,求差便可。ci
數據須要離散化get
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define low(x) (x&(-x)) #define maxn 400040 struct ss { int op,a,b; }arr[maxn/2],add[maxn/2]; int cleft[maxn],cright[maxn]; int s[maxn]; int addleft(int i,int val) { while(i<maxn) { cleft[i]+=val; i+=low(i); } } int getleft(int i) { int sum=0; while(i>0) { sum+=cleft[i]; i-=low(i); } return sum; } int addright(int i,int val) { while(i<maxn) { cright[i]+=val; i+=low(i); } } int getright(int i) { int sum=0; while(i>0) { sum+=cright[i]; i-=low(i); } return sum; } int main() { int n; int ca=1; while(~scanf("%d",&n)) { memset(cleft,0,sizeof(cleft)); memset(cright,0,sizeof(cright)); int ind=0; int ad=0; for(int i=0;i<n;i++) { scanf("%d%d",&arr[i].op,&arr[i].a); arr[i].b=arr[i].a+ad+1; s[ind++]=arr[i].a; s[ind++]=arr[i].b; if(!arr[i].op) { add[ad++]=arr[i]; } } sort(s,s+ind);//paixu ind=unique(s,s+ind)-s;//quchong printf("Case #%d:\n",ca++); for(int i=0;i<n;i++) { if(!arr[i].op){ int a=lower_bound(s,s+ind,arr[i].a)-s+1;//lisan int b=lower_bound(s,s+ind,arr[i].b)-s+1; // printf("add: %d %d %d\n",arr[i].op,a,b); int left=getleft(maxn)-getleft(a-1); int right=getright(maxn)-getright(b); printf("%d\n",max(0,left-right)); addleft(a,1); addright(b,1); } else { int id=arr[i].a-1; int a=lower_bound(s,s+ind,add[id].a)-s+1;//lisan int b=lower_bound(s,s+ind,add[id].b)-s+1; // printf("delete: id=%d %d %d\n",id,a,b); addleft(a,-1); addright(b,-1); } } } return 0; } /* 6 0 1 0 0 1 2 0 0 1 3 0 0 ans: 0 1 1 1 */
HDU5373
求n通過t次迭代變換後是否能整出11,n->n+n的每位數之和 爲一次變換
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define ll long long int s,n,t; int sum,p; void run(int n) { p=1; while(n) { p*=10; sum+=n%10; n/=10; } } int main() { int ca=1; while(~scanf("%d%d",&n,&t)) { if(n==-1&&t==-1) break; sum=0; int s=n; int ans=0; t++; while(t--) { run(s); ans=(ans*p+s)%11; s=sum; } if(ans%11==0)printf("Case #%d: Yes\n",ca++); else printf("Case #%d: No\n",ca++); } return 0; }
HDU5375
gray碼是由相鄰二進制碼兩兩抑或獲得的,第一個gray碼就是第一個二進制碼
當前的狀態只和前一狀態有關,dp分類討論便可
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; int dp[200020][2]; char s[200020]; int a[200020]; int main() { int T; scanf("%d",&T); s[0]='0'; for(int ca=1;ca<=T;ca++) { memset(dp,0,sizeof(dp)); scanf("%s",s+1); int n=strlen(s+1); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { if(s[i]=='0') { if(s[i-1]=='0')dp[i][0]=dp[i-1][0]; else if(s[i-1]=='1')dp[i][0]=dp[i-1][1]+a[i]; else dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]); } else if(s[i]=='1') { if(s[i-1]=='0')dp[i][1]=dp[i-1][0]+a[i]; else if(s[i-1]=='1')dp[i][1]=dp[i-1][1]; else dp[i][1]=max(dp[i-1][0]+a[i],dp[i-1][1]); } else{ if(s[i-1]=='0')dp[i][0]=dp[i-1][0]; else if(s[i-1]=='1')dp[i][0]=dp[i-1][1]+a[i]; else dp[i][0]=max(dp[i-1][0],dp[i-1][1]+a[i]); if(s[i-1]=='0')dp[i][1]=dp[i-1][0]+a[i]; else if(s[i-1]=='1')dp[i][1]=dp[i-1][1]; else dp[i][1]=max(dp[i-1][0]+a[i],dp[i-1][1]); } } printf("Case #%d: %d\n",ca,max(dp[n][0],dp[n][1])); } return 0; }
HDU5379
給定一棵n個節點的數,和一組編號1.2.3...n的麻將牌,要求:
1.每一個節點只能放一個麻將牌
2.父親的全部直接兒子上面的麻將牌要連續
3.全部子樹上面的麻將牌要連續
求放置的方法數。
題目就是求一個連續序列能分紅k段的方法數目,bfs求解。對於每棵子樹而言,
1.只要有兒子節點,方法數*2 (因爲是一棵樹,鄰接表中v[i].size()>1就說明有兒子。
2.有孫子的兒子節點最多隻能有兩個。
3.若是有孫子的兒子節點>=1個,方法數*2
4.沒有孫子的兒子節點數爲k個,方法數*k!
5.數據範圍longlong
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; #define ll long long #define maxn 100010 #define mod 1000000007 vector<int>s[maxn]; int n; int v[maxn]; ll ans; void bfs() { queue<int>q; memset(v,0,sizeof(v)); while(!q.empty())q.pop(); q.push(0); ans=1; v[0]=1; while(!q.empty()) { int fa=q.front(); q.pop(); int num=0; int sig=0; for(int i=0;i<s[fa].size();i++) { int su=s[fa][i]; if(!v[su]) { v[su]=1; if(s[su].size()>1)num++; else sig++; q.push(su); } } if(num>2){ ans=0; return; } if(num!=0)ans=(ans*2)%mod; for(int i=1;i<=sig;i++) { ans=(ans*i)%mod; } } } int main() { int T; scanf("%d",&T); for(int ca=1;ca<=T;ca++) { scanf("%d",&n); for(int i=0;i<=n;i++)s[i].clear(); int u,v; s[0].push_back(1); s[1].push_back(0); for(int i=0;i<n-1;i++) { scanf("%d%d",&u,&v); s[u].push_back(v); s[v].push_back(u); } bfs(); printf("Case #%d: %lld\n",ca,ans); } return 0; }