博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
codeforces B. Valera and Contest 解题报告
阅读量:4980 次
发布时间:2019-06-12

本文共 3813 字,大约阅读时间需要 12 分钟。

题目链接:

题目意思:给出6个整数, n, k, l, r, sall, sk ,需要找出一个满足下列条件的序列:1、 l <= 每一个数 <= r   2、整个序列的数的和为sall       3、取得最高分数的那k个人的总分数恰好(注意,是刚刚好,多了或少了都不可,而且这k个人的分数不一定都是相等的)等于sk。(至于后面的那句 if a1, a2, ..... sk = a1 + a2 + ... + ak 本人觉得好像没有什么多大的用处)

     wa足9次终于做出来了。一开始以为取得最高分,那么非r莫属,直接输出k 个 r 即可,接着下面的 (sallsk  )/ (n-k) 根据有无余数来继续。真的是大错特错啊~~陆陆续续修改,又没有考虑到 sall  sk  

      模拟题真的不是很难,但是要十分细心!

      我的做法是,求k个人和n-k个人的分数的做法类似,所以可以写一个函数solve来解决。 以求k个人的分数为例,前面已经交代k个人的分数不一定完全相同,也就是说有余数(sk / k 不是恰好是整数,那么就要回溯,那么令 i = 1,即 sk / k  *  (k-i) (用p3表示),剩下的数为sk-p3 。试探它是否刚好能够除得尽 i,除此,还需要满足在[l,r]的范围,当找到第一个满足条件的i即可跳出循环。 至于求n-k个,稍稍有点不同的是,求出的商还需要满足比第一次调用求出的所有数要少(题目意思啊!),其实就是要小于两个数即可,即代码中的res1 和 res2

1 #include 
2 #include
3 #include
4 using namespace std; 5 6 int n, k, l, r, sum, sumk, cnt, res1, res2; //cnt的使用是为了区别第一次的调用和第二次的调用 7 8 void solve(int p, int n) 9 {10 int i, j, p1, p2, p3, p4, p5, flag = 0;11 cnt++;12 p1 = p/n;13 if (p % n)14 {15 for (i = 1; !flag; i++)16 {17 p3 = p1 * (n - i);18 p2 = p - p3;19 if (p2 % i == 0)20 {21 p4 = p2 / i;22 if (p4 <= r && p4 >= l)23 {24 if (cnt == 1) // 第一次调用,求k个数25 {26 p5 = p4;27 flag = 1;28 res1 = p5;29 res2 = p1; 30 break;31 }32 else if (cnt == 2) // 第二次调用,求n-k个数33 {34 if (p4 <= res1 && p4 <= res2) // 这个条件好关键,保证是比第一次调用所求出的所有数要少35 {36 p5 = p4;37 flag = 1;38 break;39 }40 }41 }42 }43 }44 for (j = 0; j < n-i; j++)45 printf("%d ", p1);46 for (j = 0; j < i; j++)47 {48 if (flag)49 printf("%d ", p5);50 else51 printf("%d ", p1);52 }53 }54 else55 {56 if (cnt == 1)57 res1 = res2 = p1; // 好关键的,有可能第一次调用k个人的分数完全相等58 for (i = 1; i <= n; i++)59 printf("%d ", p1);60 }61 }62 int main()63 {64 int t1, t2;65 while (scanf("%d%d%d%d%d%d", &n, &k, &l, &r, &sum, &sumk) != EOF)66 {67 cnt = 0;68 solve(sumk, k); 69 if (sum != sumk) // 如果相等,没有必要调用第二次70 {71 t1 = sum - sumk;72 t2 = n-k; 73 solve(t1, t2);74 } 75 printf("\n");76 }77 return 0;78 }

 

    简化后的代码(参考乌冬兄的代码,这就是差距啊~~~)

  

1 #include 
2 #include
3 #include
4 #include
5 using namespace std; 6 7 int main() 8 { 9 int n, k, l, r, sall, sk, i;10 while (scanf("%d%d%d%d%d%d", &n, &k, &l, &r, &sall, &sk) != EOF)11 {12 vector
res(n,l); //n个元素,每个元素初始值为l13 sk -= k * l; //k个人分数之和的最大余数14 sall -= n * l + sk; //n-k个人分数之和的最大余数15 for (i = 0; i < k; i++)16 res[i] += sk/k; //有可能有余数的,所以后面要接着判断17 for (i = 0; i < sk%k; i++) //每一个都加,保证每个数都增长得最慢(有r限制)18 res[i]++;19 if (sall) //如果为0,说明剩下的n-k个人的分数都为l20 {21 for (i = k; i < n; i++) //注意是从k开始加,保证题目中所说的前k个人的分数是整个序列中最大的22 res[i] += sall / (n-k);23 for (i = k; i < k+sall%(n-k); i++)24 res[i]++;25 }26 for (i = 0; i < res.size(); i++)27 printf("%d ", res[i]);28 printf("\n");29 }30 return 0;31 }

 

转载于:https://www.cnblogs.com/windysai/p/3451791.html

你可能感兴趣的文章
用JAVA编写浏览器内核之实现javascript的document对象与内置方法
查看>>
centos iptables
查看>>
寻找二叉查找树中比指定值小的所有节点中最大的那个节点
查看>>
如何设置输入框达到只读效果
查看>>
RT3070 USB WIFI 在连接socket编程过程中问题总结
查看>>
MIS外汇平台荣获“2013年全球最佳STP外汇交易商”
查看>>
LeetCode 题解之Add Digits
查看>>
hdu1502 , Regular Words, dp,高精度加法
查看>>
SpringBoot在idea中的热部署配置
查看>>
MyEclipse连接SQL Server 2008数据库的操作方法
查看>>
JS验证图片格式和大小并预览
查看>>
laravel5.2 移植到新服务器上除了“/”路由 ,其它路由对应的页面显示报404错误(Object not found!)———新装的LAMP没有加载Rewrite模块...
查看>>
编写高质量代码--改善python程序的建议(六)
查看>>
windows xp 中的administrator帐户不在用户登录内怎么解决?
查看>>
接口和抽象类有什么区别
查看>>
Codeforces Round #206 (Div. 2)
查看>>
**p
查看>>
优先队列详解
查看>>
VS2012 创建项目失败,,提示为找到约束。。。。
查看>>
设计类图
查看>>