2017暑假第二阶段第八场 总结
来源:互联网 发布:淘宝怎么追加差评 编辑:程序博客网 时间:2024/06/05 13:23
T1 回文数
问题描述
给你一个数N,求出最小的B(B>=2),使得 N在 B进制下为回文数。
输入格式
第一行1个整数TEST,表示数据组数。 接下来TEST行,每行一个整数N。
输出格式
共输出TEST行,每行对应一个答案B
数据范围
30%的数据 TEST<=10,N<=10
4 。
100%的数据 TEST<=1,000,N<=1010 。
比较常见的思路是把原数写成
不妨换一种考虑的方向。考虑原数转换为B进制之后的位数,从而优雅地暴力。
首先转换后只有一位数肯定不是最优解,因为这样的话B满足B>N,然而在B=N-1时,一定是两位的回文数
如果转换后是两位数,那么一定是
如果转换后是三位数,那么最小也是
于是得出解法:首先在
#include<stdio.h>#include<cmath>#define ll long longusing namespace std;ll N;int a[65];bool check(int b){ if(!N)return true; int cnt=0,i; ll tmp=N; while(tmp) { a[++cnt]=tmp%b; tmp/=b; } for(i=1;i<=cnt-i+1;i++)if(a[i]!=a[cnt-i+1])return false; return true;}int main(){ int T; ll i,tmp; bool flag; scanf("%d",&T); while(T--) { flag=false; scanf("%lld",&N); if(N==2){puts("3");continue;} tmp=ceil(sqrt(N)); for(i=2;i<=tmp;i++) { if(check(i)) { flag=true; printf("%lld\n",i); break; } } if(flag)continue; for(i=tmp-1;i>=1;i--) { if(N%i==0&&(N/i-1)>tmp) { printf("%lld\n",N/i-1); break; } } }}
T2 奶牛阵列
问题描述
每天早晨约翰的奶牛都会在挤奶的时候排成阵列,即站成R(1<=R<=10000)行C(1<=C<=75)列的矩阵。我们知道,约翰是奶牛专家,他打算写一本关于喂养奶牛的书,他发现,当奶牛按不同血统标记以后,整个大矩阵就像由很多小矩阵无缝拼接的一样。
请帮助约翰找到面积最小的模型矩阵,使他能拼出整个大矩阵,当然,模型矩阵的尺寸不一定能整除大矩阵,也就是说你可以用若干个模型矩阵,拼出一个包含大矩阵的更大的矩阵。
输入格式
第一行, 两个整数R和C
接下来是由大写字母构成的R*C的矩阵
输出格式
一个整数,表示最小模型矩阵的面积。
样例输入
2 5
ABABA
BABAB
样例输出
4
样例说明:
模型矩阵如下:
AB
BA
拼出的大矩阵如下:
ABABAB
BABABA
根据题意,应该是不能把小矩形重叠放置的。但是由于本题数据太弱,很多错解都能AC。对于错解,这里不一一列举,正解是KMP。
不妨先把每一列考虑成一个字符,再对这些“字符”通过KMP找出“最小循环节”,即最小循环矩形,并记录长度;再把每一行也考虑成一个字符,并进行相同的操作。那么答案就是两个“长度”的乘积。KMP找最小循环矩形的正确性是显然的,求答案的操作可以通过下面的图理解:
将字符串转换为“字符”考虑后,我们仅关心两个“字符”是否相同,那么可以使用hash。如果害怕hash出错,也可以开两个hash表。但是由于数据本身太弱,这里就只开了一个。
#include<stdio.h>#define ll long long#define mod 0xffffint R,C,fail[10005],rans,cans;ll Hash[10005];char ch[10005][80];int main(){ int i,j,sd=131; ll h; scanf("%d%d",&R,&C); for(i=1;i<=R;i++)scanf("%s",&ch[i][1]); for(i=1;i<=R;i++) { h=0; for(j=1;j<=C;j++)h=(h+ch[i][j])*sd%mod; Hash[i]=h; } fail[1]=j=0; for(i=2;i<=R;i++) { while(j>0&&Hash[j+1]!=Hash[i])j=fail[j]; if(Hash[j+1]==Hash[i])j++; fail[i]=j; } rans=R-fail[R]; for(i=1;i<=C;i++) { h=0; for(j=1;j<=R;j++)h=(h+ch[j][i])*sd%mod; Hash[i]=h; } fail[1]=j=0; for(i=2;i<=C;i++) { while(j>0&&Hash[j+1]!=Hash[i])j=fail[j]; if(Hash[j+1]==Hash[i])j++; fail[i]=j; } cans=C-fail[C]; printf("%d",cans*rans);}
提供几组肉眼就能看出答案的小数据,能够卡掉很多AC代码。
/*data1: 3 9 CBABCCBBC CACBAACCA BACCCAABB 正解27 data2: 2 6 BACBAC CBCBAC 正解12 data3: 5 7 BAAAABB ABABABA ABABAAB BAAAAAA BBABABB 正解35 data4: 2 8 AAABCAAA ABABABAB 正解12 */
T3 突击队
问题描述
何老板的公司有t名员工,编号1到t.
何老板将他们分成了n组,每组员工的编号都是连续的,比如第i组[Ai,Bi]表示编号Ai,Ai+1,…,Bi都属于该组。
现何老板接到一个大单,工期很紧,需要组成一个突击组来完成任务,他想在每个组里抽出一些员工来组成突击组。现在告诉你每个组至少要抽出的人数,问,该突击组的人数最少是多少?
输入格式
第一行,一个整数n
接下来n行,每行三个整数Ai,Bi,Ci,描述一个组的情况,其中Ai,Bi表示该组员工编号的范围,Ci表示改组中至少要抽出Ci个人去突击组。
输出格式
一个整数,表示所求的答案。
数据范围
0 <= t <= 50000
1 <= n <= 50000
ai <= bi
1 <= ci <= bi - ai+1
方向对了就是道水题,如果不对什么错解都能想出来。
正解是差分约束。所有的区间的数据都可以看成前缀和相减的一个不等式。由于一个编号的人一定有一个,不会存在负数个人(废话),此外的约束条件还有:
一开始还想写个Dijkstra+Heap,结果忘了Dijkstra不能处理负权边……
#include<stdio.h>#include<queue>#include<cstring>#define Max(x,y) ((x>y)?(x):(y))#define MAXN 50005#define MAXM 150005using namespace std;int N,T;int en[MAXM],nex[MAXM],las[MAXN],len[MAXM],tot;void ADD(int x,int y,int z){ en[++tot]=y; nex[tot]=las[x]; las[x]=tot; len[tot]=z;}int dis[MAXN];bool mark[MAXN];void SPFA(int s){ int i,x,y; memset(dis,-60,sizeof(dis)); queue<int>Q; Q.push(s); dis[s]=0; while(Q.size()) { x=Q.front();Q.pop();mark[x]=false; for(i=las[x];i;i=nex[i]) { y=en[i]; if(dis[y]<dis[x]+len[i]) { dis[y]=dis[x]+len[i]; if(!mark[y])mark[y]=true,Q.push(y); } } }}int main(){ int i,x,y,z; scanf("%d",&N); for(i=1;i<=N;i++) { scanf("%d%d%d",&x,&y,&z); ADD(x-1,y,z); T=Max(T,y); } for(i=1;i<=T;i++) { ADD(i,i-1,-1); ADD(i-1,i,0); } SPFA(0); printf("%d",dis[T]);}
总结
这次考试又很爆炸,只不过收获很大,至少暴露了很多知识点的不熟悉。
T1打表找规律太久,结果发现压根就没有规律,要学会更优雅的暴力解法,思考问题的角度也要多样化,不能江化;T2正解思考的方式也很值得借鉴,KMP算法还要加强;T3主要是提醒了差分约束这种算法,太久没有用了,确实错得应该。
- 2017暑假第二阶段第八场 总结
- 2017暑假第二阶段第一场 总结
- 2017暑假第二阶段第二场 总结
- 2017暑假第二阶段第三场 总结
- 2017暑假第二阶段第四场 总结
- 2017暑假第二阶段第五场 总结
- 2017暑假第二阶段第六场 总结
- 2017暑假第二阶段第七场 总结
- 2017暑假第二阶段第九场 总结
- 第八场训练赛总结
- 大暑假集训 第二阶段
- 2015多校第八场总结
- 2010-zzuli暑假集训选拔赛四场总结
- 2017暑假集训总结
- 2017暑假集训总结
- 2017暑假总结
- 2017暑假集训总结
- 2017暑假玉泉总结
- [hdu-3622] Bomb Game题解
- 有自学前端开发的小伙伴儿吗?
- 正则表达式屏蔽关键字的方法
- 【多校训练】hdu 6125 Free from square 状压dp+分组背包
- POJ 3768 Shopping dfs+最短路
- 2017暑假第二阶段第八场 总结
- hdu 1518 Square dfs深搜算法
- OSG-获取OSG的源代码和第三方库并编译
- pycharm+pyqt5的配置(二)
- hive学习教程(二):hive的数据类型和hive的数据模型
- Prim算法求最小生成树
- Android——Context类
- 给编程生涯充电的 10 本书
- hive学习教程(三):hive的详细配置