2015 Multi-University Training Contest 7
2015-08-12 17:38
375 查看
官方题解:2015 Multi-University Training Contest 7 solutions BY UESTC
HDU 5371:http://acm.hdu.edu.cn/showproblem.php?pid=5371
题意:求最长的N-sequence
定义N-sequence由3部分组成,满足下面2个条件:
1、第一部分和第三部分相同
2、第一部分和第二部分对称
\( 1 \leqslant n \leqslant 10^5 \)
manacher算法
可以用manacher算法求出\(p[i]\),表示以下标为\(i\)和\(i+1\)为中心的最长回文长度
那么问题可以转化成,相距\(x\)的两个数\(a[i],a[i+x]\),满足\( \frac{a[i]}{2} \geqslant x\) 并且 \(\frac{a[i+x]}{2} \geqslant x\),要求\(x\)尽量大
可以枚举第一个数下标\(i\)和长度\(x\)。姿势好就可以水过。(正解是二分)
题意:将数n各位上的数加起来的和接在n末尾形成一个新的数。求进行t次这样的操作后的数是否是11的倍数
\( 1 \leqslant n \leqslant 10^4 , 1 \leqslant t \leqslant 10^5 \)
能被11整除的数的特征
奇位上的数字与偶位上的数字分别加起来,再求它们的差,如果这个差是11的倍数(包括0),那么,原来这个数就一定能被11整除。
知道这个性质之后按题意模拟就行
题意:给出一个二进制数,‘?'表示当前位为0和1都可以。以及长度为n的数组a。如果格雷码第\(i\)位为1,那么可以得到\(a_i\)点,求最多能得多少点
\( 1 \leqslant n \leqslant 2 \times 10^5 \)
格雷码转换公式:\(G_i=B_i\otimes B_{i+1}(n-1\geqslant i\geqslant 0)\)(G:格雷码,B:二进制码,最低位下标为0)
DP
\(dp[i][j]\)表示第\(i\)位为\(j\)时最大的点数
根据第\(i\)位和第\(i-1\)位的情况很容易写出状态转移方程
(待续。。。)
1003 Hotaru's problem
HDU 5371:http://acm.hdu.edu.cn/showproblem.php?pid=5371题意:求最长的N-sequence
定义N-sequence由3部分组成,满足下面2个条件:
1、第一部分和第三部分相同
2、第一部分和第二部分对称
\( 1 \leqslant n \leqslant 10^5 \)
manacher算法
可以用manacher算法求出\(p[i]\),表示以下标为\(i\)和\(i+1\)为中心的最长回文长度
那么问题可以转化成,相距\(x\)的两个数\(a[i],a[i+x]\),满足\( \frac{a[i]}{2} \geqslant x\) 并且 \(\frac{a[i+x]}{2} \geqslant x\),要求\(x\)尽量大
可以枚举第一个数下标\(i\)和长度\(x\)。姿势好就可以水过。(正解是二分)
#include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<cstring> #include<queue> #include<vector> #include<string> #include<map> using namespace std; #define pb push_back #define LL __int64 #define N 100005 #define INF 1<<30 int p[N<<1]; int s[N<<1]; int n; void init() { for(int i=n; i>=0; --i) { s[i+i+2]=s[i]; s[i+i+1]=-1; } s[0]=-2,s[n+n+2]=-3; } void manacher() { int id=0; for(int i=1; i<=2*n+1; ++i) { if(p[id]+id>i) p[i]=min(p[id-(i-id)],id+p[id]-i); else p[i]=1; while(s[i-p[i]]==s[i+p[i]]) p[i]++; if(id+p[id]<i+p[i]) id=i; } for(int i=1; i<=n; ++i) { p[i]=p[i+i+1]; } } int main() { int T,cas=1; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0; i<n; ++i) scanf("%d",&s[i]); init(); manacher(); int ans=0; for(int i=1; i<n; ++i) { for(int j=ans; j<=p[i]/2; ++j) { if(p[i]/2>=j&&p[i+j]/2>=j) ans=max(ans,j); } } printf("Case #%d: %d\n",cas++,ans*3); } return 0; }
1005 The shortest problem
HDU 5373:http://acm.hdu.edu.cn/showproblem.php?pid=5373题意:将数n各位上的数加起来的和接在n末尾形成一个新的数。求进行t次这样的操作后的数是否是11的倍数
\( 1 \leqslant n \leqslant 10^4 , 1 \leqslant t \leqslant 10^5 \)
能被11整除的数的特征
奇位上的数字与偶位上的数字分别加起来,再求它们的差,如果这个差是11的倍数(包括0),那么,原来这个数就一定能被11整除。
知道这个性质之后按题意模拟就行
#include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<cstring> #include<queue> #include<vector> #include<string> #include<map> using namespace std; #define pb push_back #define LL __int64 #define N 100005 #define INF 1<<30 int ans,sum; int k; void cal(int n) { int t=1e8,digit; while(t>n)t/=10; while(t) { digit=n/t; if(k&1) ans+=digit; else ans-=digit; sum+=digit; n=n%t; t/=10; k++; } } int main() { int n,t; int cas=1; while(scanf("%d%d",&n,&t),n!=-1||t!=-1) { k=sum=ans=0; cal(n); while(t--) { cal(sum); } if(abs(ans)%11) printf("Case #%d: No\n",cas++); else printf("Case #%d: Yes\n",cas++); } return 0; }
1007 Gray code
HDU 5375:http://acm.hdu.edu.cn/showproblem.php?pid=5375题意:给出一个二进制数,‘?'表示当前位为0和1都可以。以及长度为n的数组a。如果格雷码第\(i\)位为1,那么可以得到\(a_i\)点,求最多能得多少点
\( 1 \leqslant n \leqslant 2 \times 10^5 \)
格雷码转换公式:\(G_i=B_i\otimes B_{i+1}(n-1\geqslant i\geqslant 0)\)(G:格雷码,B:二进制码,最低位下标为0)
DP
\(dp[i][j]\)表示第\(i\)位为\(j\)时最大的点数
根据第\(i\)位和第\(i-1\)位的情况很容易写出状态转移方程
#include<cstdio> #include<algorithm> #include<iostream> #include<cmath> #include<cstring> #include<queue> #include<vector> #include<string> #include<map> using namespace std; #define pb push_back #define LL __int64 #define N 200005 #define INF 1<<30 int dp [2]; char str ; int a ; int main() { int T,cas=1; scanf("%d",&T); while(T--) { memset(dp,0,sizeof(dp)); scanf("%s",str+1); str[0]='0'; int len=strlen(str+1); for(int i=1; i<=len; ++i)scanf("%d",&a[i]); for(int i=1; i<=len; ++i) { if(str[i]=='0') { dp[i][0]=max(dp[i-1][0],(str[i-1]!='0')?dp[i-1][1]+a[i]:0); } if(str[i]=='1') { dp[i][1]=max((str[i-1]!='1')?dp[i-1][0]+a[i]:0,dp[i-1][1]); } if(str[i]=='?') { dp[i][0]=max(dp[i-1][0],(str[i-1]!='0')?dp[i-1][1]+a[i]:0); dp[i][1]=max((str[i-1]!='1')?dp[i-1][0]+a[i]:0,dp[i-1][1]); } } printf("Case #%d: %d\n",cas++,max(dp[len][0],dp[len][1])); } return 0; }
(待续。。。)
相关文章推荐
- 2015 Multi-University Training Contest 6 Solutions
- 2015 Multi-University Training Contest 1
- 2015 Multi-University Training Contest 4
- 2015 Multi-University Training Contest 5
- 2015 Multi-University Training Contest 6
- 2015 Multi-University Training Contest 2
- 2015 Multi-University Training Contest 3
- HDU 6052 暴力计数
- HDU 6053 容斥dp 或 莫比乌斯反演
- HDU 6035 树形dp
- hdu 5288 思维技巧
- HDU 3530 RMQ+twopointer/单调队列
- 2015 Multi-University Training Contest 8
- HDU 6138 AC自动机
- HDU 6169 Senior PanⅡ 数论+DP
- hdu 6162 Ch’s gift【树链剖分】
- 2017 Multi-University Training Contest - Team 8
- 2017 Multi-University Training Contest - Team 7
- 2017 Multi-University Training Contest - Team 6
- 2017 Multi-University Training Contest - Team 5