算法设计与分析期末上机考试总结
来源:互联网 发布:青瓦台风水 知乎 编辑:程序博客网 时间:2024/05/21 04:19
A约翰的零花钱 上机考试(2016)
时间限制2000ms内存限制65536KB
题目描述
约翰要对自己的花费进行规划。他首先计算得到了后面N(1<=N<=100000)天的花费money(1<=money<=10000)。然后将这N天恰好分成M(1<=M<=N)个周期。每个周期包含一个或多个连续的天数。每天只能包含在一个周期内。最后计算出每个周期的花费和。他会以最大的一个周期的花费和向妈妈要零花钱。但是妈妈说,这样太浪费钱了。所以,她让约翰对合理安排周期,使最终的给的零花钱最少。注意:这N天花费的顺序是不能改变的。
输入格式
第一行为两个数字N M,接下来有N行,每行一个整数。对于40%的数据,N<=100;对于70%的数据,N<=10000;对于100%的数据,N<=100000。
输出格式
妈妈给的最小零花钱。
输入样例
7 5
100
400
300
100
500
101
400
输出样例
500
最小零花钱的最小值是每天花费中的最大值,此时M=N;最小零花钱的最大值是所有花费的和,此时M=1。据此进行二分搜索判断最小零花钱的值。
AC代码:
时间限制1000ms内存限制65536KB
题目描述
永恒の灵魂最近得到了面积为n*m的一大块土地(高兴ING^_^),他想在这块土地上建造一所房子,这个房子必须是正方形的。但是,这块土地并非十全十美,上面有很多不平坦的地方(也可以叫瑕疵)。这些瑕疵十分恶心,以至于根本不能在上面盖一砖一瓦。他希望找到一块最大的正方形无瑕疵土地来盖房子。不过,这并不是什么难题,永恒の灵魂在10分钟内就轻松解决了这个问题。现在,您也来试试吧。
输入格式
输入文件第一行为两个整数n,m(1<=n,m<=200),接下来n行,每行m个数字,用空格隔开。0表示该块土地有瑕疵,1表示该块土地完好。
输出格式
一个整数,最大正方形的边长。
输入样例
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
输出样例
2
很简单的搜索。
AC代码:
时间限制1000ms内存限制65536 KB
题目描述
Facer今天买了n块蛋糕,不料被信息组中球球等好吃懒做的家伙发现了,没办法,只好浪费一点来填他们的嘴巴。他答应给每个人留一口,然后量了量每个人口的大小。Facer有把刀,可以切蛋糕,但他不能把两块蛋糕拼起来,但是他又不会给任何人两块蛋糕。现在问你,facer怎样切蛋糕,才能满足最多的人。(facer的刀很强,切的时候不会浪费蛋糕)。
输入格式
第一行n,facer有n个蛋糕。接下来n行,每行表示一个蛋糕的大小。再一行一个数m,为信息组的人数,然后m行,每行一个数,为一个人嘴的大小。(1≤n≤50,1≤m≤1024)
输出格式
一行,facer最多可以填多少张嘴巴。
输入样例
4
30
40
50
25
10
15
16
17
18
19
20
21
25
24
30
输出样例
7
二分+贪心判断可行解,然后再用迭代加深搜索。此题难度较大,注意到数据的范围,蛋糕和嘴的大小会有很多的重复,需要进行一些优化。
AC代码:
时间限制1000ms内存限制65536 KB
题目描述
woem公主被邪恶的大魔王抓走了!为了拯救公主,国王紧急排出了一名的勇者去挑战大魔王。大魔王有n支护卫队,每支护卫队有k个恶魔。勇者和恶魔都有攻击力和防御力,当两者发生战斗时,若一方的防御力小于另一方的攻击力,那么这一方就会死亡(所以存在两者都死亡或都存活的情况)。勇者的攻击力为1,恶魔的防御力均为0。每当勇者击杀一只恶魔并存活时,勇者的防御力就会增加1。当勇者与一支护卫队战斗时,他会按照护卫队内的顺序依次与恶魔发生战斗(恶魔们训练有素,总是排成竖线攻击)。那么勇者的初始防御力为多少时,才可以打败这些护卫队,来到魔王面前拯救woem公主呢?勇者可以决定先与哪支护卫队发生战斗,但必须击杀完一支护卫队才能挑战另一支。
输入格式
第一行两个数字n和k依次表示护卫队的数量和队内恶魔的数量。接下来n行每行k个数,为每支护卫队里的恶魔的攻击力(勇者挑战这支队时,就按顺序依次挑战)。所有恶魔的攻击力≤106。对于前四组数组n=8,k=2;对于第五组数据n=8,k=3;对于第六组数据n=16,k=3;对于第七组数据n=16,k=2;对于第八组数据n=1000,k=2;对于第九组数据n=100000,k=2;
对于第十组数据n=100000,k=3。样例不包含在测试数据中。
输出格式
一个数,表示最小的初始防御力。
输入样例
2 2
3 4
1 2
输出样例
1
设一支护卫队中恶魔的攻击力分别为a1,a2,a3,……an,则勇士挑战它们时需要的防御力是a1,a2-1,a3-2,……an-n+1中的最大值。对于每一支护卫队都计算出这个最大值,按照贪心的思想,初始勇士的防御力就是这些最大值中的最小值,勇士按照它们最大值从小到大的顺序挑战护卫队。在挑战的过程中如果发现勇士的防御力不够了,就再从初始值中加进去。下面的我的代码通过了8组数据,最后两组数据TLE。
时间限制2000ms内存限制65536KB
题目描述
约翰要对自己的花费进行规划。他首先计算得到了后面N(1<=N<=100000)天的花费money(1<=money<=10000)。然后将这N天恰好分成M(1<=M<=N)个周期。每个周期包含一个或多个连续的天数。每天只能包含在一个周期内。最后计算出每个周期的花费和。他会以最大的一个周期的花费和向妈妈要零花钱。但是妈妈说,这样太浪费钱了。所以,她让约翰对合理安排周期,使最终的给的零花钱最少。注意:这N天花费的顺序是不能改变的。
输入格式
第一行为两个数字N M,接下来有N行,每行一个整数。对于40%的数据,N<=100;对于70%的数据,N<=10000;对于100%的数据,N<=100000。
输出格式
妈妈给的最小零花钱。
输入样例
7 5
100
400
300
100
500
101
400
输出样例
500
最小零花钱的最小值是每天花费中的最大值,此时M=N;最小零花钱的最大值是所有花费的和,此时M=1。据此进行二分搜索判断最小零花钱的值。
AC代码:
#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int MAXN=100010;int n,m;int money[MAXN];long long int low,high,mid;bool judge(int k){int group=1; long long int sum=0; for(int i=n-1;i>=0;i--) { if(sum+money[i]>k) { group++; sum=money[i]; if(group>m) return false; } else sum+=money[i]; } return true; }int main(){low=-1,high=0; scanf("%d %d",&n,&m); for(int i=0;i<n;i++) {scanf("%d",&money[i]); if(low<money[i]) low=money[i]; high=high+money[i]; } while(low<high) { mid=(low+high)/2; if(judge(mid)) high=mid; else low=mid+1; } cout<<high<<endl;}B盖房子 上机考试(2016)
时间限制1000ms内存限制65536KB
题目描述
永恒の灵魂最近得到了面积为n*m的一大块土地(高兴ING^_^),他想在这块土地上建造一所房子,这个房子必须是正方形的。但是,这块土地并非十全十美,上面有很多不平坦的地方(也可以叫瑕疵)。这些瑕疵十分恶心,以至于根本不能在上面盖一砖一瓦。他希望找到一块最大的正方形无瑕疵土地来盖房子。不过,这并不是什么难题,永恒の灵魂在10分钟内就轻松解决了这个问题。现在,您也来试试吧。
输入格式
输入文件第一行为两个整数n,m(1<=n,m<=200),接下来n行,每行m个数字,用空格隔开。0表示该块土地有瑕疵,1表示该块土地完好。
输出格式
一个整数,最大正方形的边长。
输入样例
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
输出样例
2
很简单的搜索。
AC代码:
#include<iostream>#include<algorithm>using namespace std;int graph[1010][1010]; int main(){ int n,m; int ans=0; cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>graph[i][j]; if(graph[i][j]==1) ans=1; } } if(ans==0) { cout<<ans<<endl; return 0; } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(graph[i][j]) { int ii,jj; bool flag=1; for(int k=1;i+k<=n&&j+k<=m;k++) { for(ii=i;ii<=i+k&&flag;ii++) { for(jj=j;jj<=j+k&&flag;jj++) { if(!graph[ii][jj]) flag=0; } } if(flag==0) { ans=max(ans,k); break; } } } } } cout<<ans<<endl;}C切蛋糕 上机考试(2016)
时间限制1000ms内存限制65536 KB
题目描述
Facer今天买了n块蛋糕,不料被信息组中球球等好吃懒做的家伙发现了,没办法,只好浪费一点来填他们的嘴巴。他答应给每个人留一口,然后量了量每个人口的大小。Facer有把刀,可以切蛋糕,但他不能把两块蛋糕拼起来,但是他又不会给任何人两块蛋糕。现在问你,facer怎样切蛋糕,才能满足最多的人。(facer的刀很强,切的时候不会浪费蛋糕)。
输入格式
第一行n,facer有n个蛋糕。接下来n行,每行表示一个蛋糕的大小。再一行一个数m,为信息组的人数,然后m行,每行一个数,为一个人嘴的大小。(1≤n≤50,1≤m≤1024)
输出格式
一行,facer最多可以填多少张嘴巴。
输入样例
4
30
40
50
25
10
15
16
17
18
19
20
21
25
24
30
输出样例
7
二分+贪心判断可行解,然后再用迭代加深搜索。此题难度较大,注意到数据的范围,蛋糕和嘴的大小会有很多的重复,需要进行一些优化。
AC代码:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=52;const int maxm=1025;const int INF=0x7f7f7f7f;int n,m,ans,tot;//蛋糕数,人数,最优解,蛋糕的总量 int tmp[maxn],cake[maxn],mouth[maxm],sum_mouth[maxm];bool dfs(int x,int last){ if(!x) return true; if(tot<sum_mouth[x]) return false; //剩下的蛋糕如果比未分配的x个人的嘴还要小是不可行的 tot-=mouth[x]; for(int i=x!=ans&&mouth[x]==mouth[x+1]?last:1;i<=n;i++) //如果与上一个人嘴大小相同,那么上一个人若没有选前i块蛋糕这一个人也不用选 { while(i<n&&cake[i]==cake[i+1]) i++; //如果当前需要枚举的蛋糕与上一块蛋糕的大小相同只选最后的那块 if(cake[i]>=mouth[x]) { cake[i]-=mouth[x]; if(cake[i]<mouth[1]) tot-=cake[i]; //如果剩下的蛋糕大小比第一个人的嘴还小那么就没用了//将所有没用的蛋糕和已经切好的蛋糕从总蛋糕大小中减去 if(dfs(x-1,i)) { if(cake[i]<mouth[1]) tot+=cake[i]; cake[i]+=mouth[x]; tot+=mouth[x]; return true; } if(cake[i]<mouth[1]) tot+=cake[i]; cake[i]+=mouth[x]; } } tot+=mouth[x]; return false;} bool check(int m){ int mincake,pos; memcpy(tmp,cake,sizeof(cake)); //用贪心的方法每次选择符合条件的最小的蛋糕 for(int i=m;i;i--) { mincake=INF,pos=-1; for(int j=1;j<=n;j++) { if(tmp[j]>=mouth[i]&&mincake>tmp[j]) mincake=tmp[j],pos=j; } if(pos<0) return false; tmp[pos]-=mouth[i]; } return true;} int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) {scanf("%d",&cake[i]);tot+=cake[i];} scanf("%d",&m); for(int i=1;i<=m;i++) {scanf("%d",&mouth[i]);} sort(cake+1,cake+n+1); sort(mouth+1,mouth+m+1); for(int i=1;i<=m;i++) sum_mouth[i]=sum_mouth[i-1]+mouth[i]; int l=0,r=m,mid; if(check(m)) { printf("%d\n",m); return 0; } while(l+1<r) { mid=(l+r)>>1; if(check(mid)) l=mid; else r=mid; } ans=r; //得到一个近似最优解,在此基础上进行迭代加深搜索 while(dfs(ans,1)&&ans<=m) ans++; printf("%d\n",ans-1); }D挑战大魔王的勇士 上机考试(2016)
时间限制1000ms内存限制65536 KB
题目描述
woem公主被邪恶的大魔王抓走了!为了拯救公主,国王紧急排出了一名的勇者去挑战大魔王。大魔王有n支护卫队,每支护卫队有k个恶魔。勇者和恶魔都有攻击力和防御力,当两者发生战斗时,若一方的防御力小于另一方的攻击力,那么这一方就会死亡(所以存在两者都死亡或都存活的情况)。勇者的攻击力为1,恶魔的防御力均为0。每当勇者击杀一只恶魔并存活时,勇者的防御力就会增加1。当勇者与一支护卫队战斗时,他会按照护卫队内的顺序依次与恶魔发生战斗(恶魔们训练有素,总是排成竖线攻击)。那么勇者的初始防御力为多少时,才可以打败这些护卫队,来到魔王面前拯救woem公主呢?勇者可以决定先与哪支护卫队发生战斗,但必须击杀完一支护卫队才能挑战另一支。
输入格式
第一行两个数字n和k依次表示护卫队的数量和队内恶魔的数量。接下来n行每行k个数,为每支护卫队里的恶魔的攻击力(勇者挑战这支队时,就按顺序依次挑战)。所有恶魔的攻击力≤106。对于前四组数组n=8,k=2;对于第五组数据n=8,k=3;对于第六组数据n=16,k=3;对于第七组数据n=16,k=2;对于第八组数据n=1000,k=2;对于第九组数据n=100000,k=2;
对于第十组数据n=100000,k=3。样例不包含在测试数据中。
输出格式
一个数,表示最小的初始防御力。
输入样例
2 2
3 4
1 2
输出样例
1
设一支护卫队中恶魔的攻击力分别为a1,a2,a3,……an,则勇士挑战它们时需要的防御力是a1,a2-1,a3-2,……an-n+1中的最大值。对于每一支护卫队都计算出这个最大值,按照贪心的思想,初始勇士的防御力就是这些最大值中的最小值,勇士按照它们最大值从小到大的顺序挑战护卫队。在挑战的过程中如果发现勇士的防御力不够了,就再从初始值中加进去。下面的我的代码通过了8组数据,最后两组数据TLE。
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;int maxs[100010];int datas[100010][5]; int main(){ int n,k,ans=0,defense=0; scanf("%d %d",&n,&k); for(int i=0;i<n;i++) { for(int j=0;j<k;j++) { int temp; scanf("%d",&temp); datas[i][j]=temp-j; } maxs[i]=*max_element(datas[i],datas[i]+k); } int t=1000010,pos; for(int i=0;i<n;i++) { if(maxs[i]<t) { t=maxs[i]; pos=i; } } ans=t; defense=ans+k; maxs[pos]=-1; while(1) { int flag=0; for(int i=0;i<n;i++) { if(maxs[i]<=defense&&maxs[i]!=-1) { flag=1; maxs[i]=-1; defense+=k; } } if(!flag) break; } while(*max_element(maxs,maxs+n)!=-1) { int t=1000010,pos; for(int i=0;i<n;i++) { if(maxs[i]<t&&maxs[i]!=-1) { t=maxs[i]; pos=i; } } ans+=t-defense; defense+=t-defense+k; maxs[pos]=-1; while(1) { int flag=0; for(int i=0;i<n;i++) { if(maxs[i]<=defense&&maxs[i]!=-1) { flag=1; maxs[i]=-1; defense+=k; } } if(!flag) break; } } printf("%d\n",ans);}
0 0
- 算法设计与分析期末上机考试总结
- 一周搞定期末考系列之《算法分析与设计》
- 《算法设计与分析》期末复习精简版
- 算法分析与设计总结
- 算法分析与设计总结
- 算法设计与复杂性分析 第二次上机 Dynamic Median
- “计算机算法设计与分析”期末考点以及应试思路-D_Dan
- 算法分析与设计课程总结
- 大学算法分析与设计复习总结
- 算法分析与设计课程总结
- 算法分析与设计课程总结
- 算法设计与分析课程总结
- 期末总结-电力系统潮流上机计算
- 《算法设计与分析》考试说明(复习总结 与 试题提交方式、个人考勤记录——2014.05.10更新)
- 【算法】计算机算法设计与分析考试复习要点【原创技术】
- 《财务决策与分析》——期末总结(慕课组)
- CCAT-s1考试上机总结
- Linux内核分析期末总结
- iOS-分段跳转-自定义分段View
- 一个Java对象到底占多大内存?
- Debug之路-4
- Unable to start service Intent not found问题及Service无法拉起也无报错问题
- matlab中sortrows的用法
- 算法设计与分析期末上机考试总结
- SecureCRT连接linux超时问题
- ubuntu14下安装shadowsocks
- Matlab中dir命令
- 浏览器兼容问题1
- VirtualBox虚拟机与主机互通,并且虚拟机又能上网配置
- 自制滚动条
- 深入理解java异常处理机制
- oracle 显示中文乱码解决方式