2016 杭州区域赛补题
A - ArcSoft's Office Rearrangement
HDU - 5933
题意:现在有n个办公区,每个办公区内有a[i]个办公人员,现在要将这些人均匀的分布在m个办公区内,每个办公区人员必须等价。现在有两个操作,1操作,可以将相邻的两个区域的人员结合在一起,2操作可以将一个办公区的人员,随意划分成两部分,两部分不一定平均,问最少需要多少次操作。
做法:贪心,从前向后枚举,不可以的情况就是不能平均的,可以预处理出来平均值,对于可以的情况,如果比平均值小,就直接加在后一个办公区内,要是与平均值一样,就可以直接跳过,要是大于平均值,就先划分成平均值的若干份,最后不足一个平均值的加在后一个办公区内。
代码如下:
#include<stdio.h> #include<iostream>using namespace std;long long t; long long n , m; long long a[100005]; long long sum; long long num;int main() {scanf("%lld" , &t);for(long long cas = 1; cas<=t; cas++){scanf("%lld%lld" , &n , &m);sum = 0;num = 0;for(long long i=1; i<=n; i++){scanf("%lld" , &a[i]);sum += a[i];}if(sum % m != 0){printf("Case #%lld: -1\n" , cas);}else{long long tmp = sum/m; // printf("%lld..\n" , tmp);for(long long i=1; i<=n; i++){ // printf("%lld...%lld..\n" , i , a[i]);if(a[i] > tmp){num += (a[i]/tmp)-1;if(a[i]%tmp != 0){num ++; //先剥离下来num++; //再安装到下一个块上去a[i+1] += a[i]%tmp;}}else if(a[i] == tmp){continue;}else if(a[i]<tmp && a[i]!=0){num++;a[i+1] += a[i];}}printf("Case #%lld: %lld\n" , cas , num);}}return 0; }
View Code
F - Four Operations
HDU - 5938
题意:给你一个字符串,5<=len<=20,字符串由1~9的数字组成,问你向里面按顺序添加+ - * / 构成的算术运算式子结果最大是多少
做法:我们知道肯定让x+y尽可能的大,a*b/c的结果尽可能小,于是a*b的结果尽可能小,c尽可能大。
于是我们枚举“/”的位置,后面的作为c,a,b都只占一位 前面的作为x+y,一直x+y的长度之后,例如12121,那么和要尽可能大,要么就是1+2121,要么就是1212+1,因为这样可以保证尽可能长的长度,为什么要枚举除法的位置,而不是直接取最后一位,给前面省长度呢,因为可能a*b很大,c很小,导致我们减去的东西很大,比一位所带来的影响还要大,例如224591,所以需要枚举"/"的位置
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h>using namespace std;int t; char s[25]; int len; long long sum[25]; long long maxx;long long num(int l , int r) {long long res = 0;for(int i=l; i<=r; i++){res = res*10+(s[i]-'0');}return res; }int main() {scanf("%d" , &t);for(int cas=1; cas<=t; cas++){scanf("%s" , s);len = strlen(s);maxx = -100000000000000000; // printf("%lld..\n" , maxx);for(int i=0; i<len; i++){ // sum[i] =0; // for(int j=0; j<i; j++) // { // sum[i] = max(sum[i] , num(0,j)+num(j+1,i)); // }sum[i] = max(num(1,i)+(s[0]-'0') , num(0,i-1)+(s[i]-'0')); // printf("%d..%lld..\n" , i , sum[i]); }for(int i=4; i<len; i++){maxx = max(maxx , sum[i-3]-((s[i-2]-'0')*(s[i-1]-'0')/num(i,len-1))); // printf("%d...%lld...\n" , i , maxx); }printf("Case #%d: %lld\n" , cas , maxx);}return 0; }/* 100 999999999999999999991224591224591 */
View Code
C - Car
HDU - 5935
题意:现在一个人驾车行驶,保证全程不减速,现在给出了n个测速点,保证测速点一定是在整秒的时候测量的,问这个人通过这n个测速点最快的时间
做法:正向的,全程不减速不好写,对于每一段,你无法确定速度与时间,如果这一段比上一段长,你就直接设置成一秒,那万一下一段很短,岂不是前面的设置都错了;
于是我们反向想,倒过来就是全程不加速,那么最后一段一定是一秒,速度最大,这样可以保证全程时间尽可能的短,于是最后一段的时间与速度都是知道的,那么前一段的速度要小于这一段,时间要尽可能的短,于是整除向上取整即可,记得更新速度,即可解决
坑点:不能直接计算速度v 精度卡的非常的死 必须保存距离与时间
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<math.h> #include<string.h>using namespace std;int t; int n; long long b[100005]; long long a[100005]; //long long num1 , num2;void debug() {for(int i=1; i<=n; i++){printf("%d..%lld...\n" ,i , a[i]);} }int main() {scanf("%d" , &t);for(int cas=1; cas<=t; cas++){scanf("%d" , &n); // num1 = 0;b[0] = 0;for(int i=1; i<=n; i++){scanf("%lld" , &b[i]); // a[i] = num2-num1; // num1 = num2; }sort(b+1 , b+1+n);for(int i=1; i<=n; i++){a[i] = b[i]-b[i-1];} // debug();long long ans = 1; // double v = a[n]*1.00;long long tmp;tmp = 1;for(int i=n-1; i>=1; i--){tmp = ceil((1.00*a[i]*tmp)/a[i+1]); // printf("%d..%lld..\n" , i , tmp);ans += tmp;}printf("Case #%d: %lld\n" , cas , ans);}return 0; }
View Code
B - Bomb
HDU - 5934
题意:现在有一对炸弹,要全部都引爆,每个炸弹有自己的圆心和半径,引爆之后在范围内的炸弹都会被引爆,问引爆所有炸弹所需要的最小的花费。n<=1e3
做法:刚开始的做法是,首先,我们可以根据引爆范围n^2的建图,有向图,入度为零的是一定要点的,它所能到达的点全部都删去, 剩下的就是在连通块中找最小花费的点了。剩下的这部分我是直接联通快中招最小点的。 这样是一定不对的,例如,1-2 2-3 3-1 2-4 4的值最小,但是引爆4并不能引爆1,2,3. 于是,只有在同一个强连通分量里面才可以求最小值,剩下的就是入度为零的全部引爆了 于是,先缩点,形成DAG之后求 Tarjan的时间复杂度O(n+m) 缩点时间复杂度O(n^2) 求解O(n)
代码如下:
/* 刚开始的做法是:首先,我们可以根据引爆范围n^2的建图,有向图,入度为零的是一定要点的,它所能到达的点全部都删去, 剩下的就是在连通块中找最小花费的点了。剩下的这部分我是直接联通快中招最小点的。 这样是一定不对的,例如,1-2 2-3 3-1 2-4 4的值最小,但是引爆4并不能引爆1,2,3. 于是,只有在同一个强连通分量里面才可以求最小值,剩下的就是入度为零的全部引爆了 于是,先缩点,形成DAG之后求 Tarjan的时间复杂度O(n+m) 缩点时间复杂度O(n^2) 求解O(n) */ #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<math.h>using namespace std;const int maxn = 1003;int t; int n;struct CIRCLE {double x,y;double r;int c; }circle[maxn];double dis(int i , int j) {return sqrt((circle[i].x-circle[j].x)*(circle[i].x-circle[j].x)+(circle[i].y-circle[j].y)*(circle[i].y-circle[j].y)); }void input() {for(int i=1; i<=n; i++){scanf("%lf%lf%lf%d" , &circle[i].x , &circle[i].y , &circle[i].r , &circle[i].c);} }struct EDGE {int to , next; }edge[maxn*maxn]; int head[maxn] , tot; //int head2[maxn] , tot2; int ans; int du[maxn];int low[maxn] , dfn[maxn] , Stack[maxn] , num[maxn];///num记录缩点之后每个点的大小 int belong[maxn]; int index , scc , top; bool InStack[maxn];void init() {memset(head , -1 , sizeof(head));tot = 0; // memset(head2 , -1 , sizeof(head2)); // tot2 = 0;ans = 0;for(int i=1; i<=n; i++){num[i] = 10004;}memset(du , 0 , sizeof(du)); }void add(int u , int v) {edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++; }//void add2(int u , int v) //{ // edge2[tot2].to = v; // edge2[tot2].next = head2[u]; // head2[u] = tot2++; //}void build() {for(int i=1; i<=n; i++){for(int j=1; j<=n; j++){if(j == i) continue;if(dis(i , j) <= circle[i].r){add(i , j);}}} }void Tarjan(int u) {int v;low[u] = dfn[u] = ++index;Stack[top++] = u;InStack[u] = true;for(int i=head[u]; i!=-1; i=edge[i].next){v = edge[i].to;if( !dfn[v] ){Tarjan(v);if( low[u] > low[v] ){low[u] = low[v];}}else if(InStack[v] && low[u] > dfn[v]){low[u] = dfn[v];}}if(low[u] == dfn[u]){scc++;do{v = Stack[--top];InStack[v] = false;belong[v] = scc;num[scc] = min(num[scc] , circle[v].c);}while(v!=u);} }void solve() {memset(dfn , 0 , sizeof(dfn));memset(InStack , false , sizeof(InStack));index = scc = top = 0;for(int i=1; i<=n; i++){if( !dfn[i] ){Tarjan(i);}}for(int i=1; i<=n; i++){for(int j=head[i]; j!=-1; j=edge[j].next){int tmp = edge[j].to;if(belong[i] != belong[tmp]){ // add2(belong[i] , belong[tmp]);du[belong[tmp]]++;}}}}int main() {scanf("%d" , &t);for(int cas=1; cas<=t; cas++){scanf("%d" , &n);init();input();build();solve();for(int i=1; i<=scc; i++){if(du[i] == 0){ans += num[i];}}printf("Case #%d: %d\n" , cas , ans);}return 0; }
View Code
D - Difference
HDU - 5936
题意:现在定义一个操作,对于正整数,强调一下,是正整数,数字y的每一位的K次方-y=x,现在给定了x与k,求有多少种满足条件的y
做法:x = F(y,k)-y
因为 y > 0
所以 x > F(y,k)
因为 题目给定 x > 0
所以 F(y,k) > y
所以x > F(y,k) > y
所以y的长度不超过x的长度10位,将y分成两部分,低位部分a和高位部分b
设 F(Y,K) = F(a,k) +F(b,k);
x = F(a,k) +F(b,k)-a- b*1e5;
x-F(a,k)+a = F(b,k)-b*1e5
y 的个数就是使上式成立的数字的个数
于是枚举等式前边的数字,时间复杂度O(100000),预处理出来等式后边的,排序之后二分查找使之成立的个数即可
感谢:https://blog.csdn.net/luricheng/article/details/70176894提供思路与坑点
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<math.h>using namespace std;const long long maxn = 100050;long long F[maxn]; long long t; long long x , k; long long ans[maxn];long long poww(long long n ,long long m) {long long res = 1;for(long long i=1; i<=m; i++){res *= n;}return res; }void init() {memset(F , 0 , sizeof(F));for(long long i=0; i<100000; i++){long long j = i;while( j ){F[i] += poww(j%10 , k);j /= 10;}ans[i] = F[i]-(i*100000);}sort(ans , ans+100000); }void debug() {for(long long i=0; i<=100; i++){printf("%lld...%lld...%lld\n" , i , F[i] , ans[i]);} }long long sea(long long xx) {long long L , R;L = lower_bound(ans , ans+100000 , xx)-ans;if(ans[L] != xx)return 0;R = upper_bound(ans , ans+100000 , xx)-ans;R--;if(ans[R] != xx)return 0;return R-L+1; }long long solve() {long long res;res = 0;for(long long i=0; i<100000; i++){long long tmp = sea(x-F[i]+i);res += tmp;}return res; }int main() {scanf("%lld" ,&t);for(long long cas=1; cas<=t; cas++){scanf("%lld%lld" , &x , &k);init(); // debug();long long tmp = solve();if(x == 0)tmp--;printf("Case #%lld: %lld\n" , cas , tmp);}return 0; }
View Code
E - Equation
HDU - 5937
题意:现在你有一些数字卡片,每个数字卡片上写有1~9中的一个,给你的是每一个数字有多少张卡片,问你能够组成多少种不一样的等式。
A+B=C 与 B+A=C 定义为不一样的
思路:感谢https://www.cnblogs.com/jihe/p/6024135.html不然这个bug我能de一年
直接暴力哪几个被选了就好,但是不能这样暴力,就是你现在选的是第x个,下一个选第几个,因为这样只让我们的暴力数量变多,我们其实想要的就是这个有没有被选就好了
那么就从第一个开始,看他作为第i个的时候,下一个作为第i+1个,与此同时,下一层就是我不作为第i层,i+1作为第i层,这样可以覆盖所有的情况
代码如下:
/* 错因: 首先不剪枝会WA 其次,问的是会出现多少种不一样的,而不是多少个 多少种的话,就可以整一个vis数组,最大容量是2,也就是2+3=5与3+2=5不一样 但是容量是2的时候和直接保存两个有区别吗? 试一下*/#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h>using namespace std;struct NODE {int a , b , c; } node[40]; int t; int maxx; int a[15]; int rem; int flag;void pre() {int tot = 0;for(int i=1; i<9; i++){for(int j=1; i+j<=9; j++){node[tot].a = i;node[tot].b = j;node[tot].c = i+j; // printf("%d..%d..%d..%d..\n" , tot , i , j , i+j);tot++;}} }void init() {maxx = 0;flag = 1;rem = 0; }void input() {for(int i=1; i<=9; i++){scanf("%d" , &a[i]);a[i] = min(a[i] , 17-i);rem += a[i];if(a[i] < 17-i)flag = 0;} }bool ok(int xx) {if(a[node[xx].a]>=0 && a[node[xx].b]>=0 && a[node[xx].c]>=0)return true;return false; }void dfs(int x , int dep , int sheng) {if(36-x+dep<=maxx) ///后面的全都可以也不行的话 就直接跳出return ;if(dep >= 36)return ;a[node[x].a] -= 1;a[node[x].b] -= 1;a[node[x].c] -= 1;if(ok(x)){maxx = max(maxx , dep+1);dfs(x+1 , dep+1 , sheng-3);}a[node[x].a] += 1;a[node[x].b] += 1;a[node[x].c] += 1;dfs(x+1 , dep , sheng); }void solve() {dfs(0 , 0 , rem); }int main() {pre();scanf("%d" , &t);for(int cas=1; cas<=t; cas++){init();input(); // printf("%d...\n" , rem);if(flag){printf("Case #%d: 36\n" , cas);continue;}solve();printf("Case #%d: %d\n" , cas , maxx);}return 0; }
View Code
转载于:https://www.cnblogs.com/Flower-Z/p/9703607.html
2016 杭州区域赛补题相关推荐
- icpc 2020沈阳区域赛补题
2020沈阳区域赛 H 这题是一道典型dp 但是需要用滚动数组优化空间, 在状态转移的时候需要考虑一下是否满足天数条件. 我真的吐了,debug改了半天之后发现错误原因是: 排序应该是 sort(v+ ...
- 2019ICPC上海区域赛 补题(12/13) 总结
前言: 个人的 ICPCICPCICPC 第一站,还是值得记录一下的(虽然咕到现在才记录),总体而言体验很不错,比赛兼旅游.这套题总体印象就是树树树图,作为队里数据结构兼图论选手,这次也确实写了大部分 ...
- 2020ICPC南京区域赛 补题 总结
前言 第一次打线上 ICPC\text{ICPC}ICPC ,记录一下.听说鸭血粉丝汤很好吃,虽然我没吃到,衣服也不赖.比赛环境方面,由于使用自己的设备,还是比较舒服的. 不晓得怎么,一到正式赛,前期 ...
- 华为杯数学建模优秀论文_数学建模经典例题(2016年国赛B题与优秀论文)
数学建模经典例题 (更多往期经典例题可点击文章最后相关推荐哦) 相关推荐 数学建模经典例题(2000年国赛B题与解题思路) 数学建模经典例题(2001年国赛A题与优秀论文) 数学建模经典例题(2001 ...
- 第七届蓝桥杯 2016年省赛真题(Java 大学C组)
蓝桥杯 2016年省赛真题(Java 大学C组) 第一题:有奖猜谜 第二题:煤球数目 第三题:平方怪圈 第四题:骰子游戏 第五题:分小组 第六题:凑算式 第七题:搭积木 第八题:冰雹数 第九题:四平方 ...
- 林大5.1训练赛补题
林大5.1训练赛补题 A.凸多边形曼哈顿 E.矩阵快速幂 I.线段dp A.凸多边形曼哈顿 题意:给你一个凸多边形,问你当其中K边形的最大dis[]是多少? 思路:首先是要发现K>=4的时候答案 ...
- HDU 3220 Alice’s Cube (09年上海区域赛水题(位压缩、逆向搜索、打表))
这道题是09年上海区域赛的A题,虽然很水,但是不能直接爆搜,直接爆搜要T.于是我们看到题目的要求是说当操作的步数大于3的时候就输出more,那么我们可以从终态枚举进行了三次操作所能达到的所有状态,这个 ...
- 2021山东省省赛补题
cf传送门 前言 在gym看到,知道山东省很nb所以写了. 补题含大量借鉴大佬代码() F Birthday Cake 题意:给定n个串,求有多少对串能拼出平方串(能够表示成两个相同的字符串连接在一起 ...
- 2017乌鲁木齐区域赛D题Fence Building
题目链接:点击打开链接 现场赛的时候想了一个整场都没推出来,xjb推出个式子来也不会写最后打铁...一直都知道这是一道公式题,就是不知道是啥公式,赛后才知道得用欧拉公式...平面内的区域个数=平面内的 ...
最新文章
- kafka partition分配_kafka的分区分配策略
- 第十六届全国大学生智能车竞赛山东赛区成绩汇总
- 基于STM32F103RE ADDA板制作
- 不走寻常路 IBM云计算解决方案解读
- 给thinkphp加个分页样式
- 数据结构笔记(四)-- 静态链表实现
- 编译用户Orcle的package中访问其它Schema的表
- 职称计算机和英语有效性,2015职称计算机考试突破小诀窍
- 【转】如何调试bash脚本
- 记一次破解blob加密视频网站的过程
- 计算机专业研究生平均月薪,广东:计算机专业研究生月薪过万 本科生学针灸推拿工资最高...
- VS2015 保护视力 背景色设置
- 鼠标移动到指定行会变色
- POJ - 1679 The Unique MST (次小生成树) 板子
- 数据数值转换factorize和dummy
- 贼好玩!我用Python写了一个AI玩星际争霸2!
- .loc 与.iloc
- html五角星代码,五角星评分系统.html
- percona toolkit系列(gh-ost)
- 启用Windows沙盒
热门文章
- TensorFlow教程使用RNN生成唐诗
- 湖北省小学生计算机大赛,喜讯!我市文昌小学雷梓铭斩获湖北省中小学电脑制作活动创客项目一等奖...
- Python 爬虫 之 Selenium 模拟打开操作浏览器爬取斗鱼全部视播相关信息,并json保存信息
- python使用面向对象思想开发一个人机对战的猜拳游戏(石头剪刀布)
- LED驱动电源雷击浪涌防护
- 【PC工具】白领办公必备,电脑定时提醒休息护眼软件:眼睛护士
- Java项目:SSH电子相册管理系统
- ElementUI中使用ECharts
- 腾讯Angel Graph团队刷新GNN最强榜单OGB世界纪录!
- tcga数据下载_使用R下载TCGA数据