ACM_瑞士轮及其解答
大学ACM考试题目及作业答案整理
ACM作业与答案整理1、平面分割方法:设有n条封闭曲线画在平面上,而任何两条封闭曲线恰好相交于两点,且任何三条封闭曲线不相交于同一点,问这些封闭曲线把平面分割成的区域个数。
#include <iostream.h>int f(int n){if(n==1) return 2;else return f(n-1)+2*(n-1);}void main(){int n;while(1){cin>>n;cout<<f(n)<<endl;}}2、LELE的RPG难题:有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.编程全部的满足要求的涂法.#include<iostream.h>int f(int n){if(n==1) return 3;else if(n==2) return 6;else return f(n-1)+f(n-2)*2;}void main(){int n;while(1){cin>>n;cout<<f(n)<<endl;}}3、北大ACM(1942)Paths on a GridTime Limit: 1000MS Memory Limit: 30000K DescriptionImagine you are attending your math lesson at school. Once again, you are bored because your teacher tells things that you already mastered years ago (this time he's explaining that (a+b)2=a2+2ab+b2). So you decide to waste your time with drawing modern art instead.Fortunately you have a piece of squared paper and you choose a rectangle of size n*m on the paper. Let's call this rectangle together with the lines it contains a grid. Starting at the lower left corner of the grid, you move your pencil to the upper right corner, taking care that it stays on the lines and moves only to the right or up. The result is shown on the left:Really a masterpiece, isn't it? Repeating the procedure one more time, you arrive with the picture shown on the right. Now you wonder: how many different works of art can you produce?InputThe input contains several testcases. Each is specified by two unsigned 32-bit integers n and m, denoting the size of the rectangle. As you can observe, the number of lines of the corresponding grid is one more in each dimension. Input is terminated by n=m=0.OutputFor each test case output on a line the number of different art works that can be generated using the procedure described above. That is, how many paths are there on a grid where each step of the path consists of moving one unit to the right orone unit up? You may safely assume that this number fits into a 32-bit unsigned integer.Sample Input5 41 10 0Sample Output1262#include<iostream>using namespace std;longlong f(long long m, long long n){if(n==0) return 1;else return f(m-1,n-1)*m/n;}int main(){longlongm,n;while(scanf("%I64d %I64d",&n,&m) &&n+m){printf("%I64d\n",f(m+n,min(m,n)));}return 0;}1、(并查集)若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。
ACM_瑞士轮_C++类方法
return 1; } return -1; }
void Match::init() {
qsort(player[1],count,sizeof(Player),compare); }
void Match::newRound() {
int i = 0;
for(i = 0;i < count; i = i + 2) {
Description
【背景】 在双人对决的竞技性比赛,如乒乓球、羽毛球、国际象棋中,最常见的赛 制是淘汰赛和循环赛。前者的特点是比赛场数少,每场都紧张刺激,但偶 然性较高。后者的特点是较为公 平,偶然性较低,但比赛过程往往十分冗长。 本题中介绍的瑞士轮赛制,因最早使用于 1895 年在瑞士举办的国际象棋 比赛而得名。它可以看作是淘汰赛与循环赛的折衷,既保证了比赛的稳定 性,又能使赛程不至于过长。
Match::Match() { }
Match::~Match() {
delete [] player[0]; delete [] player[1]; }
Match::Match(int r,int c) {
round = r; count = c; m = 1; player[0] = new Player[count]; player[1] = new Player[count]; }
ACM软件大赛之编程大赛题目(附部分答案)
ACM 软件大赛之编程大赛比赛注意事项:l 比赛时间为3小时(小时(180180分钟);比赛分两个阶段:第一阶段限时30分钟,完成公示的3题,第二阶段限时150分钟(事先完成第一阶段题目的小组可提前进入第二阶段); l 比赛第一阶段的3道题目将在前期宣传中告知参赛选手,比赛第二阶段的题目将由赛事主席当场公布竞赛题目;主席当场公布竞赛题目;l 前两阶段题目分为三个分值(前两阶段题目分为三个分值(55分、分、1010分、分、1515分),第一阶段3道公示题都为5分;第二阶段总共15道题,根据不同的难度分值不同,分别为5道5分题,分题,55道10分题,分题,55道15分题;第一阶段参赛队员不可参考任何相关资料;第二阶段参赛队员可以携带诸如书,如书,手册,程序清单等参考资料。
手册,程序清单等参考资料。
手册,程序清单等参考资料。
比赛过程中队员不得携带任何电子媒质的资料;参比赛过程中队员不得携带任何电子媒质的资料;参赛者可以选择自己擅长的语言(赛者可以选择自己擅长的语言(C,C++,JAVA C,C++,JAVA 等等)进行编写等等)进行编写l 考虑到大一和大二学生的知识掌握程度,大一参加选手一开始就会有10分的分数,最后总分是由所做题目及初始的10分相加得到。
分相加得到。
l 每组队员根据安排使用电脑,小组人数为两人的使用一台电脑,超过两人的使用两台电脑,每台的电脑配置完全相同;脑,每台的电脑配置完全相同;l 各小组每做完一题或几题,必须交予评委老师运行,评委老师当场给分;各小组每做完一题或几题,必须交予评委老师运行,评委老师当场给分; l 如在比赛中发现作弊等行为,将取消比赛资格。
如在比赛中发现作弊等行为,将取消比赛资格。
第一阶段公示题目:题目一:(5分) 打印以下图形,纵遵从字母顺序,行字符数遵从斐波那契数列ABCCDDD EEEEEFFFFFFFFGGGGGGGGGGGGG#include<iostream>int f(int x){int a = 1 , b = 0;int max_ = x;int sum = 0; for(int i = 0; i < max_ ; i++){sum = a + b;a = b;b = sum;}return sum;}void loop_print(int num,char chr){for(int i = 0; i < num ;i++)std::cout<<chr;std::cout<<"\n";}int main(){int line_max = 7;char chr = 'A';for(int line = 0; line < line_max; line++){loop_print(f(line+1),chr);chr++;}return 0;}题目二:(5分)有个电子钟,12点显示为12:00(即12小时制),那么请问一天24时间内,出现连续3个相同数字的钟点有几个?#include<iostream>using namespace std;bool check(int me){int h= me/100;int m= me-100*h;return h<=12&&m<=59&&h>0?true:false;//12小时制小时制}int main(){int me=0;int j(0);//总计数器总计数器while( me<1270){//max 12:59int t= me;int n[4];for(int i=0;i<4;i++){n[i]=t%10;t /= 10;}if(n[1]==n[2]&&(n[0]==n[1]||n[3]==n[1])&&check( me)){//cout<<n[3]<<n[2]<<":"<<n[1]<<n[0]<<"\n";//testj++;me++;}cout<<"total: "<<j*2<<endl;}题目三:(5分)10进制的四位数中有几个符合如下特征:将其分别表示为16进制、10进制、12进制,在每种状态下,分别将各个位上的数相加,能得到3个相等10进制数。
acm算法经典例题
一、数论1: Wolf and Rabbit描述There is a hill with n holes around. The holes are signed from 0 to n-1.A rabbit must hide in one of the holes. A wolf searches the rabbit in anticlockwise order. The first hole he get into is the one signed with 0. Then he will get into the hole every m holes. For example, m=2 and n=6, the wolf will get into the holes which are signed 0,2,4,0. If the rabbit hides in the hole which signed 1,3 or 5, she will survive. So we call these holes the safe holes.输入The input starts with a positive integer P which indicates the number of test cases. Then on the following P lines,each line consists 2 positive integer m and n(0<m,n<2147483648).输出For each input m n, if safe holes exist, you should output "YES", else output "NO" in a single line.样例输入21 22 2样例输出NOYES翻译:描述一座山有n个洞,洞被标记为从0到n-1。
acm程序 循环题目
acm程序循环题目
以下是两道常见的 ACM 循环题目:
1. 水桶挑战赛:一个 n 个人组成的队伍在 m 个水桶中轮流取水,每个人只能取一个水桶的水,且每个水桶的水量不同。
要求每个人取水的总时间不超过 t 分钟。
求出每个人取水的最优策略。
2. 循环赛日程表:给定 n 个队伍,需要安排一场循环赛,每个队伍都要与
其他所有队伍进行一场比赛,并且每个队伍只进行一场比赛。
要求找出一种最优的比赛日程表,使得每个队伍等待的时间最短。
这两道题目都是经典的 ACM 循环题目,考察的是循环和动态规划的思想。
在解决这类问题时,需要注意循环的起点和终点,以及循环中每个状态的含义和转移方程。
同时,还需要注意状态压缩和记忆化搜索等优化技巧的使用。
noip2011瑞士轮
对于100%的数据,1 ≤N≤100,000,1 ≤R≤50,1 ≤Q≤2N,0 ≤s1, s2, …, s2N ≤10^8,1 ≤w1,w2, …, w2N ≤10^8。
这个数据告诉我们:使用快速排序只能拿到50-60分。
可是我却把它直接忽略了。
(不知道怎么回事,我写了快速排序只拿到了10分,后面的40分莫名其妙丢掉了,不知道为什么。
)现在我是C++的OIER,所以就直接使用C++的sort函数(sort当然不能AC 50分)。
我在vijos 50分的代码:#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <algorithm>using namespace std;struct sportsman{int id,score,power;}V[200005];int N,R,Q;void start_contest(){for(int i=1;i<=N;i+=2)if(V[i].power>V[i+1].power)V[i].score++;elseV[i+1].score++;}bool compare(sportsman a,sportsman b){if(a.score==b.score)return a.id<b.id;elsereturn a.score>b.score;}int main(){//freopen("swiss.in","r",stdin);scanf("%d %d %d",&N,&R,&Q);N*=2;for(int i=1;i<=N;i++){V[i].id=i;int score;scanf("%d",&score);V[i].score=score;}for(int i=1;i<=N;i++){int power;scanf("%d",&power);V[i].power=power;}sort(V+1,V+N+1,compare);for(int i=1;i<=R;i++){start_contest();sort(V+1,V+N+1,compare);}printf("%d\n",V[Q].id);return 0;}然后我就想到了优化最后一轮比赛(调用nth_element函数优化)不过根本也没有优化多少,还是50分。
codeforces round 900 题解
Codeforces Round 900 题解一、概述Codeforces是一个知名的上线编程比赛评台,每周都有各种比赛活动,吸引了全球各地的程序员参与。
而Round 900则是其中一次比赛,本文将对该比赛中的题目进行详细解析,希望能帮助读者更好地理解并掌握相关算法知识。
二、题目解析1. 题目 1题目描述:给定一个长度为n的字符串,将其所有字母进行重新排列,使得相邻的字母不相同。
求重新排列后的最长长度。
解题思路:利用贪心算法,遍历字符串,尽可能地将相同字母进行分割,重新排列。
最终得到的字符串长度即为所求。
2. 题目 2题目描述:给定一个n行m列的矩阵,每个单元格中有一个非负整数。
将矩阵中的某一行或某一列中所有元素都加上一个给定的值k,求经过加值操作后矩阵中的最大元素。
解题思路:遍历矩阵,求得每一行和每一列的最大值,然后再根据题意进行加值操作,最终得到的矩阵中的最大元素即为所求。
3. 题目 3题目描述:给定一个长度为n的整数序列,求其中的一个连续子序列,使得该子序列的元素之和尽可能大,同时要求子序列的长度不超过k。
解题思路:利用动态规划算法,维护一个长度为k的滑动窗口,遍历整个序列,不断更新窗口中元素之和的最大值,最终得到的和即为所求。
4. 题目 4题目描述:给定一个长度为n的字符串,求其中的一个最长回文子串。
解题思路:利用动态规划算法,遍历字符串,维护一个二维数组表示子串的回文性,根据动态转移方程不断更新数组,最终得到的最长回文子串即为所求。
5. 题目 5题目描述:给定一个无向图,求其中的一条最短路径,使得路径上经过的边的权值的异或和尽可能大。
解题思路:利用Dijkstra算法求最短路径,同时维护最大异或和,最终得到的路径即为所求。
三、算法实现1. 题目 1的贪心算法实现```c++string rearrangeString(string s) {int n = s.size();vector<int> count(26, 0);for (char c : s) {count[c - 'a']++;}priority_queue<p本人r<int, char>> pq; for (int i = 0; i < 26; ++i) {if (count[i] > 0) {pq.push({count[i], i + 'a'});}}string res = "";p本人r<int, char> prev = {-1, '#'};while (!pq.empty()) {p本人r<int, char> cur = pq.top();pq.pop();res += cur.second;if (prev.first > 0) {pq.push(prev);}cur.first--;prev = cur;}if (n != res.size()) {return "";}return res;}```2. 题目 2的矩阵操作实现```c++int maxAfterAddition(vector<vector<int>> mat, int k) { int n = mat.size(), m = mat[0].size();vector<int> rowMax(n, INT_MIN), colMax(m, INT_MIN); for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {rowMax[i] = max(rowMax[i], mat[i][j]);colMax[j] = max(colMax[j], mat[i][j]);}}int ans = INT_MIN;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {int newMax = max(rowMax[i]+k, colMax[j]+k);ans = max(ans, newMax);}}return ans;}```3. 题目 3的动态规划实现```c++int maxSumSubarray(vector<int> nums, int k) { int n = nums.size();vector<int> dp(n, 0);int sum = 0, maxSum = 0;for (int i = 0; i < n; ++i) {sum += nums[i];if (i >= k) {sum -= nums[i-k];}maxSum = max(maxSum, sum);dp[i] = maxSum;}return maxSum;}```4. 题目 4的动态规划实现```c++string longestPalindromeSubstr(string s) {int n = s.size();vector<vector<bool>> dp(n, vector<bool>(n, false)); int maxLen = 1, start = 0;for (int i = 0; i < n; ++i) {dp[i][i] = true;}for (int len = 2; len <= n; ++len) {for (int i = 0; i < n-len+1; ++i) {int j = i+len-1;if (len == 2) {if (s[i] == s[j]) {dp[i][j] = true;maxLen = len;start = i;}} else {if (s[i] == s[j] dp[i+1][j-1]) {dp[i][j] = true;maxLen = len;start = i;}}}}return s.substr(start, maxLen);}```5. 题目 5的Dijkstra算法实现```c++int findMaxXor(vector<vector<p本人r<int, int>>> graph, int n, int start, int end) {priority_queue<p本人r<int, int>> pq;pq.push({start, 0});vector<int> dist(n, INT_MAX);dist[start] = 0;while (!pq.empty()) {p本人r<int, int> cur = pq.top();pq.pop();int u = cur.first, dis = -cur.second;if (u == end) {return dis;}for (auto e : graph[u]) {int v = e.first, w = e.second;if (dist[v] > (dist[u] ^ w)) {dist[v] = dist[u] ^ w;pq.push({v, -dist[v]});}}}return -1;}```四、总结通过对Codeforces Round 900中的五道题目进行详细解析,我们不仅学习了相关算法思想和技巧,还掌握了如何运用这些算法来解决实际问题。
河北省邢台市2024高三冲刺(高考数学)统编版(五四制)真题(培优卷)完整试卷
河北省邢台市2024高三冲刺(高考数学)统编版(五四制)真题(培优卷)完整试卷一、单选题:本题共8小题,每小题5分,共40分 (共8题)第(1)题半正多面体(semiregular solid)亦称“阿基米德多面体”,是由边数不完全相同的正多边形围成的多面体,体现了数学的对称美,二十四等边体就是一种半正多面体,如图,棱长为2的正方体截去八个一样的四面体就得到二十四等边体,则该二十四等边体的体积为()A.B.C.D.第(2)题已知向量,,若向量在向量上的投影向量为,则实数的值为()A.B.C.D.第(3)题每年6月到9月,昆明大观公园的荷花陆续开放,已知池塘内某种单瓣荷花的花期为3天(第四天完全凋谢),池塘内共有2000个花蕾,第一天有10个花蕾开花,之后每天花蕾开放的数量都是前一天的2倍,则在第几天池塘内开放荷花的数量达到最大()A.6B.7C.8D.9第(4)题设,当变化时的最小值为()A.B.C.D.第(5)题已知三棱锥中,分别为棱的中点,则直线与所成角的正切值为()A.B.C.D.第(6)题小明爬楼梯每一步走1级台阶或2级台阶是随机的,且走1级台阶的概率为,走2级台阶的概率为.小明从楼梯底部开始往上爬,在小明爬到第4级台阶的条件下,他走了3步的概率是()A.B.C.D.第(7)题已知集合,,则()A.B.C.D.第(8)题已知是锐角三角形,角,,所对的边分别为,,,为的面积,,则的取值范围为()A.B.C.D.二、多选题:本题共3小题,每小题6分,共18分 (共3题)第(1)题在美国重压之下,中国芯片异军突起,当前我们国家生产的最小芯片制程是7纳米.某芯片生产公司生产的芯片的优秀率为0.8,现从生产流水线上随机抽取5件,其中优秀产品的件数为.另一随机变量,则()A.B.C.D.随的增大先增大后减小第(2)题已知,则()A .的最小正周期是B.在上单调递减C.,D.的值域是第(3)题已知是半径为2的圆O的内接三角形,则下列说法正确的是()A .若角,则B.若,则C.若,则,的夹角为D.若,则为圆O的一条直径三、填空题:本题共3小题,每小题5分,共15分 (共3题)第(1)题已知向量与的夹角为,,,则________第(2)题已知是夹角为的两个单位向量,若,则k的值为_______.第(3)题若实数,满足约束条件,则的最小值为_________.四、解答题:本题共5小题,每小题15分,最后一题17分,共77分 (共5题)第(1)题已知函数,若为实数,且方程有两个不同的实数根.(1)求的取值范围:(2)①证明:对任意的都有;②求证:.第(2)题函数,.(1)若在点处的切线与直线平行,求的值;(2)若,设,试证明存在唯一零点,并求的最大值.第(3)题设函数(1)求曲线在点处的切线方程;(2)若函数有两个极值点,求实数的取值范围;(3)当时,恒成立,求实数的取值范围.第(4)题的内角,,的对边分别为,,,已知,且的面积为.(1)求的值;(2)若是边的中点,,求的长.第(5)题已知函数,其中,为自然对数的底数.(1)若,,证明:当时,;当时,(2)若,函数在区间内不单调,求的取值范围。
整理出ACM所有题目和答案解析
1000 A + B ProblemProblem DescriptionCalculate A + B.InputEach line will contain two integers A and B. Process to end of file.OutputFor each case, output A + B in one line.Sample Input1 1Sample Output2AuthorHDOJ代码:#include<stdio.h>int main(){int a,b;while(scanf("%d %d",&a,&b)!=EOF)printf("%d\n",a+b);}1001 Sum ProblemProblem DescriptionHey, welcome to HDOJ(Hangzhou Dianzi University Online Judge).In this problem, your task is to calculate SUM(n) = 1 + 2 + 3 + ... + n.InputThe input will consist of a series of integers n, one integer per line.OutputFor each case, output SUM(n) in one line, followed by a blank line. You may assume the result will be in the range of 32-bit signed integer.Sample Input1100Sample Output15050AuthorDOOM III解答:#include<stdio.h>main(){int n,i,sum;sum=0;while((scanf("%d",&n)!=-1)){sum=0;for(i=0;i<=n;i++)sum+=i;printf("%d\n\n",sum);}}1002 A + B Problem IIProblem DescriptionI have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.InputThe first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line consists of two positive integers, A and B. Notice that the integers are very large, that means you should not process them by using 32-bit integer. You may assume the length of each integer will not exceed 1000.OutputFor each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line is the an equation "A + B = Sum", Sum means the result of A + B. Note there are some spaces int the equation. Output a blank line between two test cases.Sample Input21 2112233445566778899 998877665544332211Sample OutputCase 1:1 +2 = 3Case 2:112233445566778899 + 998877665544332211 = 1111111111111111110AuthorIgnatius.L代码:#include <stdio.h>#include <string.h>int main(){char str1[1001], str2[1001];int t, i, len_str1, len_str2, len_max, num = 1, k; scanf("%d", &t);getchar();while(t--){int a[1001] = {0}, b[1001] = {0}, c[1001] = {0}; scanf("%s", str1);len_str1 = strlen(str1);for(i = 0; i <= len_str1 - 1; ++i)a[i] = str1[len_str1 - 1 - i] - '0';scanf("%s",str2);len_str2 = strlen(str2);for(i = 0; i <= len_str2 - 1; ++i)b[i] = str2[len_str2 - 1 - i] - '0';if(len_str1 > len_str2)len_max = len_str1;elselen_max = len_str2;k = 0;for(i = 0; i <= len_max - 1; ++i){c[i] = (a[i] + b[i] + k) % 10;k = (a[i] + b[i] + k) / 10;}if(k != 0)c[len_max] = 1;printf("Case %d:\n", num);num++;printf("%s + %s = ", str1, str2);if(c[len_max] == 1)printf("1");for(i = len_max - 1; i >= 0; --i){printf("%d", c[i]);}printf("\n");if(t >= 1)printf("\n");}return 0;}1005 Number SequenceProblem DescriptionA number sequence is defined as follows:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.Given A, B, and n, you are to calculate the value of f(n).InputThe input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.OutputFor each test case, print the value of f(n) on a single line.Sample Input1 1 31 2 100 0 0Sample Output25AuthorCHEN, ShunbaoSourceZJCPC2004RecommendJGShining代码:#include<stdio.h>int f[200];int main(){int a,b,n,i;while(scanf("%d%d%d",&a,&b,&n)&&a&&b&&n) {if(n>=3){f[1]=1;f[2]=1;for(i=3;i<=200;i++){f[i]=(a*f[i-1]+b*f[i-2])%7; if(f[i-1]==1&&f[i]==1)break;}i-=2;n=n%i;if(n==0)printf("%d\n",f[i]);elseprintf("%d\n",f[n]);}elseprintf("1\n");}return 0;}1008 ElevatorProblem DescriptionThe highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It costs 6 seconds to move the elevator up one floor, and 4 seconds to move down one floor. The elevator will stay for 5 seconds at each stop.For a given request list, you are to compute the total time spent to fulfill the requests on the list. The elevator is on the 0th floor at the beginning and does not have to return to the ground floor when the requests are fulfilled.InputThere are multiple test cases. Each case contains a positive integer N, followed by N positive numbers. All the numbers in the input are less than 100. A test case with N = 0 denotes the end of input. This test case is not to be processed.OutputPrint the total time on a single line for each test case.Sample Input1 23 2 3 1Sample Output1741AuthorZHENG, JianqiangSourceZJCPC2004RecommendJGShining代码:#include<stdio.h>int a[110];int main(){int sum,i,n;while(scanf("%d",&n)&&n!=0){for(i=1;i<=n;i++)scanf("%d",&a[i]);sum=0;a[0]=0;for(i=1;i<=n;i++){if(a[i]>a[i-1])sum+=6*(a[i]-a[i-1]);elsesum+=4*(a[i-1]-a[i]);sum+=5;}printf("%d\n",sum);}return 0;}1009 FatMouse' TradeProblem DescriptionFatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean.The warehouse has N rooms. The i-th room contains J[i] pounds of JavaBeans and requires F[i] pounds of cat food. FatMouse does not have to trade for all the JavaBeans in the room, instead, he may get J[i]* a% pounds of JavaBeans if he pays F[i]* a% pounds of cat food. Here a is a real number. Now he is assigning this homework to you: tell him the maximum amount of JavaBeans he can obtain.InputThe input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers J[i] and F[i] respectively. The last test case is followedby two -1's. All integers are not greater than 1000.OutputFor each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of JavaBeans that FatMouse can obtain.Sample Input5 3 7 2 4 3 5 2 20 3 25 18 24 15 15 10 -1 -1Sample Output13.333 31.500AuthorCHEN, YueSourceZJCPC2004RecommendJGShining代码:#include<stdio.h>#include<string.h>#define MAX 1000int main(){int i,j,m,n,temp;int J[MAX],F[MAX];double P[MAX];double sum,temp1;scanf("%d%d",&m,&n);while(m!=-1&&n!=-1){sum=0;memset(J,0,MAX*sizeof(int));memset(F,0,MAX*sizeof(int));memset(P,0,MAX*sizeof(double));for(i=0;i<n;i++){ scanf("%d%d",&J[i],&F[i]); P[i]=J[i]*1.0/((double)F[i]); }for(i=0;i<n;i++){for(j=i+1;j<n;j++){if(P[i]<P[j]){temp1=P[i]; P[i]=P[j]; P[j]=temp1;temp=J[i]; J[i]=J[j]; J[j]=temp;temp=F[i]; F[i]=F[j]; F[j]=temp;}}}for(i=0;i<n;i++){if(m<F[i]){ sum+=m/((double)F[i])*J[i]; break; }else { sum+=J[i]; m-=F[i]; }}printf("%.3lf\n",sum); scanf("%d%d",&m,&n);}return 0;}1021 Fibonacci AgainProblem DescriptionThere are another kind of Fibonacci numbers: F(0) = 7, F(1) = 11, F(n) = F(n-1) + F(n-2) (n>=2).InputInput consists of a sequence of lines, each containing an integer n. (n < 1,000,000).OutputPrint the word "yes" if 3 divide evenly into F(n).Print the word "no" if not.Sample Input12345Sample OutputnonoyesnononoAuthorLeojayRecommendJGShining#include<stdio.h>int main(){long n;while(scanf("%ld",&n) != EOF) if (n%8==2 || n%8==6)printf("yes\n");elseprintf("no\n");return 0;}1089 A+B for Input-Output Practice(I)Problem DescriptionYour task is to Calculate a + b.Too easy?! Of course! I specially designed the problem for acm beginners.You must have found that some problems have the same titles with this one, yes, all these problems were designed for the same aim.InputThe input will consist of a series of pairs of integers a and b, separated by a space, one pair of integers per line.OutputFor each pair of input integers a and b you should output the sum of a and b in one line, and with one line of output for each line in input.Sample Input1 510 20Sample Output630AuthorlcyRecommendJGShining解答:#include<stdio.h>main(){int a,b;while(scanf("%d%d",&a,&b)!=EOF)printf("%d\n",a+b);}1090 A+B for Input-Output Practice(II)Problem DescriptionYour task is to Calculate a + b.InputInput contains an integer N in the first line, and then N lines follow. Each line consists of a pair of integers a and b, separated by a space, one pair of integers per line.OutputFor each pair of input integers a and b you should output the sum of a and b in one line, and with one line of output for each line in input.Sample Input21 510 20Sample Output630AuthorlcyRecommendJGShining解答:#include<stdio.h>#define M 1000void main(){int a ,b,n,j[M],i;//printf("please input n:\n");scanf("%d",&n);for(i=0;i<n;i++){scanf("%d%d",&a,&b);//printf("%d %d",a,b);j[i]=a+b;}i=0;while(i<n){printf("%d",j[i]);i++;printf("\n");}}1091 A+B for Input-Output Practice(III)Problem DescriptionYour task is to Calculate a + b.InputInput contains multiple test cases. Each test case contains a pair of integers a and b, one pair of integers per line. A test case containing 0 0 terminates the input and this test case is not to be processed.OutputFor each pair of input integers a and b you should output the sum of a and b in one line, and with one line of output for each line in input.Sample Input1 510 200 0Sample Output630AuthorlcyRecommendJGShining解答:#include<stdio.h>main(){int a,b;scanf("%d %d",&a,&b);while(!(a==0&&b==0)){printf("%d\n",a+b);scanf("%d %d",&a,&b);}}1092 A+B for Input-Output Practice(IV)Problem DescriptionYour task is to Calculate the sum of some integers.InputInput contains multiple test cases. Each test case contains a integer N, and then N integers follow in the same line. A test case starting with 0 terminates the input and this test case is not to be processed.OutputFor each group of input integers you should output their sum in one line, and with one line of output for each line in input.Sample Input4 1 2 3 45 1 2 3 4 5Sample Output1015AuthorlcyRecommendJGShining解答:#include <stdio.h>int main(){int n,sum,i,t;while(scanf("%d",&n)!=EOF&&n!=0){sum=0;for(i=0;i<n;i++){scanf("%d",&t);sum=sum+t;}printf("%d\n",sum);}}1093 A+B for Input-Output Practice(V)Problem DescriptionYour task is to calculate the sum of some integers.InputInput contains an integer N in the first line, and then N lines follow. Each line starts with a integer M, and then M integers follow in the same line.OutputFor each group of input integers you should output their sum in one line, and with one line of output for each line in input.Sample Input24 1 2 3 45 1 2 3 4 5Sample Output1015Authorlcy解答:#include<stdio.h>main(){int n,a,b,i,j,sum;sum=0;while(scanf("%d\n",&n)!=-1){for(i=0;i<n;i++){scanf("%d",&b);for(j=0;j<b;j++){scanf("%d",&a);sum+=a;}printf("%d\n",sum);sum=0;}}}1094 A+B for Input-Output Practice(VI)Problem DescriptionYour task is to calculate the sum of some integers.InputInput contains multiple test cases, and one case one line. Each case starts with an integer N, and then N integers follow in the same line.OutputFor each test case you should output the sum of N integers in one line, and with one line of output for each line in input.Sample Input4 1 2 3 45 1 2 3 4 5Sample Output1015AuthorlcyRecommendJGShining解答:#include<stdio.h>main(){int n,a,b,i,j,sum;sum=0;while(scanf("%d\n",&n)!=-1){for(j=0;j<n;j++){scanf("%d",&a);sum+=a;}printf("%d\n",sum);sum=0;}}[ Copy to Clipboard ][ Save to File]1095 A+B for Input-Output Practice(VII)Problem DescriptionYour task is to Calculate a + b.InputThe input will consist of a series of pairs of integers a and b, separated by a space, one pair of integers per line.OutputFor each pair of input integers a and b you should output the sum of a and b, and followed by a blank line.Sample Input1 510 20Sample Output630AuthorlcyRecommendJGShining解答:#include<stdio.h>main(){int a,b;while(scanf("%d%d",&a,&b)!=EOF)printf("%d\n\n",a+b);}1096 A+B for Input-Output Practice(VIII)Problem DescriptionYour task is to calculate the sum of some integers.InputInput contains an integer N in the first line, and then N lines follow. Each line starts with a integer M, and then M integers follow in the same line.OutputFor each group of input integers you should output their sum in one line, and you must note that there is a blank line between outputs.Sample Input34 1 2 3 45 1 2 3 4 53 1 2 3Sample Output10156AuthorlcyRecommendJGShining解答:int main(){int a,b,i,j,l[1000],k;scanf("%d",&i);getchar();for(j=1;j<=i;j++)l[j]=0;for(j=1;j<=i;j++){scanf("%d",&a);getchar();for(k=1;k<=a;k++){scanf("%d",&b);getchar();l[j]+=b;}}for(j=1;j<=i-1;j++)printf("%d\n\n",l[j]);printf("%d\n",l[i]);}1176 免费馅饼Problem Description都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。
educational codeforces round 5 -回复
educational codeforces round 5 -回复题目: "educational codeforces round 5"赛题解析引言:在计算机科学领域的竞赛中,Codeforces是一个非常受欢迎的在线评测平台。
其中,“educational codeforces round 5”是一场以教育为主题的比赛。
在本文中,我们将一步一步地回答与这场比赛相关的问题,并深入探讨其教育性质以及对竞赛程序员的影响。
第一节: 赛事概述教育性比赛的目标是提供一个学习和成长的机会,让参赛者能够在竞争激烈的环境中提高自己的技能。
这就是为什么教育性比赛要注重考察对各个知识领域的综合运用,而不仅仅是考验竞赛者的速度和能力。
在"educational codeforces round 5"中,比赛组织者将选择一系列的问题,这些问题通常涉及广泛的主题,包括数学、算法设计和实现等。
第二节: 科目的选择比赛科目的选择对于教育性比赛的成功至关重要。
"educational codeforces round 5"赛事组织者通常会选择那些在计算机科学领域广泛使用,对竞赛程序员来说特别重要的科目。
一个典型的例子是算法和数据结构题目,这些题目考察了竞赛者对基本算法和数据结构的掌握程度。
对于一场好的教育性比赛来说,主题的多样性非常重要。
因此,组织者可能还会设计一些涉及动态规划、图论、贪心算法等题目,以确保竞赛者在各个领域都能得到锻炼。
第三节: 题目难度在保证教育性的前提下,比赛组织者需要根据参赛者的水平设置合适的题目难度。
这样一来,所有参赛者都能感到有挑战性,并有机会在比赛中学到新的知识和技能。
在"educational codeforces round 5"中,赛题的难度通常是从简单到复杂、从基础到高阶递进的。
这种渐进式的设计可以确保参赛者能够逐步提高自己的技术水平,并更好地应对高级挑战。
acm基础试题及答案
acm基础试题及答案1. 题目:给定一个整数数组,请找出数组中第二大的数。
答案:我们可以使用排序的方法,将数组从小到大排序,然后数组中的倒数第二个数就是第二大的数。
或者使用一次遍历的方法,首先初始化两个变量,一个用来存储最大值,一个用来存储第二大的值。
遍历数组,每次比较当前元素与最大值,如果当前元素大于最大值,则更新第二大的值为最大值,并将当前元素赋给最大值;如果当前元素小于最大值但大于第二大的值,则更新第二大的值。
2. 题目:实现一个函数,计算一个字符串中字符出现的次数。
答案:可以使用哈希表来实现,遍历字符串中的每个字符,将其作为键值对存储在哈希表中,键是字符,值是该字符出现的次数。
遍历结束后,哈希表中存储的就是每个字符出现的次数。
3. 题目:给定一个链表,删除链表的倒数第n个节点,并且返回新的链表头节点。
答案:可以使用双指针的方法,首先初始化两个指针,都指向链表的头节点。
然后移动第一个指针,移动n步,此时第一个指针指向倒数第n个节点的前一个节点。
接着同时移动两个指针,直到第一个指针到达链表的末尾,此时第二个指针指向的节点就是需要删除的节点的前一个节点。
然后更新第二个指针的next指针,使其指向第二个指针的next节点的next节点,最后返回链表的头节点。
4. 题目:编写一个函数,判断一个整数是否是回文数。
回文数是指正序和倒序读都一样的数。
答案:首先将整数转换为字符串,然后使用双指针的方法,一个指针从字符串的开始位置,一个指针从字符串的结束位置,向中间移动。
如果两个指针指向的字符不相等,则该整数不是回文数。
如果遍历结束后没有发现不相等的字符,则该整数是回文数。
5. 题目:给定一个字符串,找出其中不含有重复字符的最长子串的长度。
答案:可以使用滑动窗口的方法,维护一个哈希表记录窗口内字符的出现情况,以及一个变量记录不含有重复字符的最长子串的长度。
遍历字符串,每次移动窗口的右端点,如果当前字符不在窗口内,则更新最长子串的长度,并将字符添加到哈希表中。
ACM算法设计实验题目汇总
ACM算法设计实验题目汇总ACM 算法设计实验题目汇总1020 Permutation with Repetition 1 1021 双色Hanoi 塔问题 3 1022 Search Number 4 1023 整数划分问题 5 1024 Counting 6 1025 输油管道问题 81026 Integer Factorization 9 1027 邮局选址问题 11 1031 矩阵连乘问题 131032 最长公共子序列 14 1033 MAX SUM 161034 NumberTriangles17 1035 编辑距离问题181036PebbleMerging19 1037 租用游艇问题211038 Minimal m Sums 22 1040 KnapsackProblem 24 1041 最优装载251042 Lecture Halls261043 程序存储问题291048 Optimal Services 301049 汽车加油问题301059 子集树问题321060 0-1 Knapsack 331061 排列树问题361062 Problem D General Search 381020 Permutation with RepetitionDescriptionR={ r1,r2,… ,rn }是要进行排列的n 个元素。
其中元素r1,r2,… ,rn可能相同。
试设计一个算法,列出R的所有不同排列。
编程任务:给定n 以及待排列的n 个元素。
计算出这n 个元素的所有不同排列。
Input输入由多组测试数据组成。
每组测试数据的第1 行是元素个数n,1 <= n <= 500。
接下来的1 行是待排列的n 个元素。
Output对应每组输入,将计算出的n 个元素的所有不同排列输出,每种排列单独一行。
最后1 行中的数是排列总数。
Sample Input4aaccSample Outputaacc acac acca caac caca ccaa 6#include <stdio.h>#include <algorithm>using namespace std ;int ans ;int ok(char str[],int a ,int b ){if( b > a)for(int i = a ; i< b ; i++)if( str[i] == str[b] ) return 0 ;return 1 ;}void perm(char str[],int k ,int m){int i ;if( k == m ){ans ++ ;for( i = 0 ;i <= m ;i++ ) {printf("%c",str[i] ) ;}printf("\n") ;}else{for( i = k ; i <= m ;i++)if( ok(str,k,i) ){swap( str[k],str[i] );perm(str, k+1 , m );swap(str[k],str[i] ) ;}}}int main(int argc, char* argv[]){char str[1000];int n ;while( scanf("%d",&n) != EOF ) {ans = 0 ;scanf("%s",str ) ;perm(str,0,n-1) ;printf("%d\n",ans );}return 0;}1021 双色Hanoi塔问题DescriptionA、B、C 是3个塔座。
ACM算法题以及答案
在做这些题目之前必须了解vector(数组),list(链表)、deque(双端队列)、queue(队列),priority_queue(优先队列)Stack(栈)、set(集合)、map(键值对),mutilset、mutilmap。
stack堆栈,没有迭代器,支持push()方法。后进先出,top()返回最顶端的元素,pop()剔除最顶元素
定义queue对象的示例代码如下:
queue<int> q1;
queue<double> q2;
queue的基本操作有:
入队,如例:q.push(x);将x接到队列的末端。
出队,如例:q.pop();弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
#include <vector>
vector属于std命名域的,因此需要通过命名限定,如下完成你的代码:
using std::vector; vector<int> v;
或者连在一起,使用全名:
std::vector<int> v;
建议使用全局的命名域方式:
using namespace std;
list不支持随机访问。所以没有 at(pos)和operator[]。
list对象list1, list2 分别有元素list1(1,2,3),list2(4,5,6) 。list< int>::iterator it;
list成员
说明
constructor
构造函数
destructor
析构函数
ACM算法题以及答案
ACM算法题使用C++实现在做这些题目之前必须了解vector(数组),list(链表)、deque(双端队列)、queue(队列), priority_queue(优先队列)Stack(栈)、set(集合)、map(键值对),mutilset、mutilmap。
stack堆栈,没有迭代器,支持push()方法。
后进先出,top()返回最顶端的元素,pop()剔除最顶元素deque双端队列,支持迭代器,有push_back()方法,跟vector差不多,比vector多了个pop_front,push_front方法queue队列,先进先出,不支持迭代器,有push()方法,pop()剔除第一个元素,front()返回第一个元素vector使用vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。
vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
为了可以使用vector,必须在你的头文件中包含下面的代码:#include <vector>vector属于std命名域的,因此需要通过命名限定,如下完成你的代码:using std::vector; vector<int> v;或者连在一起,使用全名:std::vector<int> v;建议使用全局的命名域方式:using namespace std;1.vector的声明vector<ElemType> c; 创建一个空的vectorvector<ElemType> c1(c2); 创建一个vector c1,并用c2去初始化c1vector<ElemType> c(n) ; 创建一个含有n个ElemType类型数据的vector;vector<ElemType> c(n,elem); 创建一个含有n个ElemType类型数据的vector,并全部初始化为elem;c.~vector<ElemType>(); 销毁所有数据,释放资源;2.vector容器中常用的函数。
ACM必做50题的解题-高精度
POJ 1001 Exponentiation高精度数的计算,以前在网上看到过一个计算大数阶乘比如10000000!的算法,总体思想就是将结果用数组保存起来,然后将结果的每一位与乘数相乘,当然还有进位...有了这个算法的思想,这个题思路就可以是:先将输入的小数转换成一个整数,当然这个整数肯定能够用int类型的变量保存,比如1.2345, 通过函数 removeDot()将它转化成12345,然后利用大数阶乘的思想计算12345*12345.....*12345, 最后的就是输出了,这个要考虑的情况比较多,因为这个也WA了5次才AC(笨的要死), 情况虽多,但不难.这道题是高精度计算的,不算很难,但是很繁琐,尤其是对输入输出的要求。
被这道题搞了好久,耐心来,一点一点调试,总会成功的。
#include<iostream>#include<string>#include<math.h>using namespace std;char ans[10];char res[2][205];__int64 ps;//有几位小数点int len;//长度,R的有效长度//计算c = b * avoid Multiply(char * b,int bt,char * a,int at,char * c){int i,j;int up=0;for(i=0;i<at;++i){up=0;for(j=0;j<bt;j++){int t;if(c[i+j]==0)c[i+j]='0';t=(a[i]-48)*(b[j]-48)+c[i+j]-48+up;if(t>=10){up=t/10;t=t%10;c[i+j]=t+48;if(j==(bt-1) )c[i+j+1]=(up+48);}else{c[i+j]=t+48;up=0;}}}}int main(){string str;int n;int i,j;int s,t;int pos;while(cin>>str>>n){i=5;pos=str.find('.',0);if(pos<0)//没有小数点{ps=0;//zs=zs*n;//后面为0的总数}else//有小数点{ps=(5-pos);ps=ps*n;//小数位总数}memset(ans,0,sizeof(ans));memset(res[0],0,sizeof(res[0])); memset(res[1],0,sizeof(res[1])); t=5;s=0;while(str[s]=='0' || str[s]=='.') s++;j=0;for(i=t;i>=s;--i){if(str[i]=='.')continue;ans[j]=str[i];j++;}len=j;strcpy(res[0],ans);strcpy(res[1],ans);for(i=2;i<=n;++i){memset(res[(i+1)%2],0,sizeof(res[0]));Multiply(res[i%2],strlen(res[i%2]),ans,len,res[(i+1)%2]); }int L=strlen(res[(n+1)%2]);int d=(n+1)%2;if(ps>0){j=0;while(res[d][j]=='0')j++;if(ps>=L){printf(".");for(i=ps-1;i>=j ;--i){if(i>=L)printf("0");elseprintf("%c",res[(n+1)%2][i]);}}else{if(j>=ps){for(i=L-1;i>=ps;--i)printf("%c",res[(n+1)%2][i]);}else{for(i=L-1;i>=j ;--i){if(i==ps){printf("%c.",res[(n+1)%2][i]);}elseprintf("%c",res[(n+1)%2][i]);}}}}else{for(i=L-1;i>=0;--i)printf("%c",res[(n+1)%2][i]);}printf("\n");}return 0;}POJ 1047 Round and Round We Go题意:输入一个数,要求判该数是否为循环数.依次将该数分别于2到len(输入的数的位数)相乘,在乘的过程中,判断数发生了变化没有,如果发生了变化,则直接输出该数不是循环数,没有必要再继续乘下去,而如果是循环数,则一直需要乘下去.#include<iostream>#include<string>#include<cstdlib>#include<algorithm>using namespace std;int num[70];int ans[70];char ss[70];bool match[70];int main(){int i,j,k,len;bool flag;while(scanf("%s",ss)!=EOF){len=strlen(ss);for(i=len-1,j=0;i>=0;i--,j++)num[j]=ss[i]-'0';for(i=2;i<=len;i++){memset(ans,0,sizeof(ans));for(j=0;j<len;j++) //依次将该数与2到len之间的数相乘ans[j]=num[j]*i;for(j=0;j<len;j++) //循环处理进位if(ans[j]>=10){ans[j+1]+=ans[j]/10;ans[j]%=10;}memset(match,0,sizeof(match)); //match数组用来标记数的匹配情况flag=true;for(j=0;j<len;j++){k=0;while(k<len){if(ans[k]==num[j]&&!match[k]) //两数字相等且没有进行标记{match[k]=true;break;}k++;}if(k==len) //此时说明相乘后的结果发生了改变{flag=false;break;}}if(!flag){printf("%s is not cyclic\n",ss);break;}}if(flag)printf("%s is cyclic\n",ss);}system("pause");return 0;}POJ 1131 Octal Fractions给定一个八进制的小数题目要求你把它转换为十进制小数,转换后小数的位数是转换前八进制小数位数的3倍且不输出末尾无意义的零(即后置零). 我采用的方法是乘10然后对8取整(现在假设将p进制的小数转换为n进制,同样采用乘n取整:),每转换一位,都必须从最低位s[len-1]开始至小数的最高位(即小数点后的一位),每次计算积 g=a[j]*n+k(其中k为下一位积的进位),本位进位数 k=g/p,积在本位存入 s[j]=g%p;最后的整数k作为转换的一位存放于转换结果字符串中。
acm编程例题 参考答案
acm编程例题参考答案ACM编程例题参考答案ACM(Advanced Computer Mathematics)是一种面向计算机科学与技术的竞赛形式,旨在提高参与者的编程技能和解决问题的能力。
ACM编程例题是指在ACM竞赛中出现的一系列编程题目,这些题目涵盖了各种算法和数据结构的应用。
本文将给出一些ACM编程例题的参考答案,希望能够帮助读者更好地理解和掌握这些题目的解法。
一、题目一:最大公约数题目描述:给定两个正整数a和b,求它们的最大公约数。
解题思路:最大公约数可以通过欧几里得算法来求解。
该算法的基本思想是,两个正整数的最大公约数等于其中较小的数和两数之差的最大公约数。
具体的实现可以使用递归或循环的方式。
代码示例:```c++int gcd(int a, int b) {if (b == 0) {return a;}return gcd(b, a % b);}```二、题目二:素数判断题目描述:给定一个正整数n,判断它是否为素数。
解题思路:素数是只能被1和自身整除的正整数。
判断一个数是否为素数可以使用试除法,即从2开始,依次判断n是否能被2到sqrt(n)之间的数整除。
如果存在能整除n的数,则n不是素数;否则,n是素数。
代码示例:```c++bool isPrime(int n) {if (n <= 1) {return false;}for (int i = 2; i * i <= n; i++) {if (n % i == 0) {return false;}}return true;}```三、题目三:字符串反转题目描述:给定一个字符串s,将其反转后输出。
解题思路:字符串反转可以通过将字符串的首尾字符依次交换来实现。
可以使用双指针的方式,一个指针指向字符串的首字符,另一个指针指向字符串的尾字符,然后交换两个指针所指向的字符,并向中间移动,直到两个指针相遇。
代码示例:```c++void reverseString(string& s) {int left = 0;int right = s.length() - 1;while (left < right) {swap(s[left], s[right]);left++;right--;}}```四、题目四:二分查找题目描述:给定一个有序数组和一个目标值,使用二分查找算法在数组中找到目标值的索引,如果目标值不存在,则返回-1。
ACM程序大赛选拔初赛试题 - 参考答案
a[n]=n+1; int x=0; while(n>=1) {
if(a[i]!=0) {
if(x%2==0) { if(n==2) printf("\n"); printf("%d ",a[i]); n--; a[i]=0; } x++; } if(i+1>=size) i=0; else i++; } }
4、解方程 难度系数:★★☆☆☆
(注意此题只供 10 级的同学,08,09 级的同学请做第三题) 题意:形如 ax2+bx+c=d 的方程。其中 a,c,d 均为整数,b 为正整数。请你用计算机求出对 应的 x 的值(只考虑实数根)。
输入:依次输入 a,b,c,d 的值。注意:只要输入一组数据。用空格隔开。
char temp,str[10]; scanf("%s",str);
for(int i=0;i<9;i++) for(int j=i+1;j<10;j++) if(str[i]>str[j]) { temp=str[i]; str[i]=str[j]; str[j]=temp; }
cout<<str<<endl; }
输入:依次输入函数的四个系数中的 a,b,c,d 的值。用空格隔开。
输出:如果有极值点则全部输出,结果保留两位小数,格式为“(x1=#,y1=#) (x2=#,y2=#)”,如果没有则输入“no answer。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Description
【背景】
在双人对决的竞技性比赛,如乒乓球、羽毛球、国际象棋中,最常见的赛
制是淘汰赛和循环赛。
前者的特点是比赛场数少,每场都紧张刺激,但偶
然性较高。
后者的特点是较为公
平,偶然性较低,但比赛过程往往十分冗长。
本题中介绍的瑞士轮赛制,因最早使用于 1895 年在瑞士举办的国际象棋比赛而得名。
它可以看作是淘汰赛与循环赛的折衷,既保证了比赛的稳定
性,又能使赛程不至于过长。
【问题描述】
2*N名编号为 1~2N的选手共进行 R轮比赛。
每轮比赛开始前,以及所有比赛结束后,都会按照总分从高到低对选手进行一次排名。
选手的总分
为第一轮开始前的初始分数加上已
参加过的所有比赛的得分和。
总分相同的,约定编号较小的选手排名靠前。
每轮比赛的对阵安排与该轮比赛开始前的排名有关:第 1 名和第 2 名、第 3 名和第 4 名、……、第 2K –1 名和第 2K名、……、第 2N –
1 名和第2N名,各进行一场比赛。
每场比赛胜者得 1 分,负者得 0 分。
也就是说除了首轮以外,其它轮比赛的安排均不能事先确定,而是要取决于选手在之前比赛中的表现。
现给定每个选手的初始分数及其实力值,试计算在 R 轮比赛过后,排名
第 Q 的选手编号是多少。
我们假设选手的实力值两两不同,且每场比赛
中实力值较高的总能获胜。
Input
输入的第一行是三个正整数 N、R、Q,每两个数之间用一个空格隔开,表示有 2*N 名选手、R 轮比赛,以及我们关心的名次 Q。
第二行是 2*N个非负整数 s
1, s
2
, …, s
2N
,每两个数之间用一个空格隔
开,其中 s
i
表示编号为 i 的选手的初始分数。
第三行是 2*N个正整数 w
1, w
2
, …, w
2N
,每两个数之间用一个空格隔开,
其中 w
i
表示编号为 i 的选手的实力值。
Output
输出只有一行,包含一个整数,即 R 轮比赛结束后,排名第 Q 的选手的编号。
Sample Input
2 4 2
7 6 6 7
10 5 20 15
Sample Output
1
Hint
对于 30%的数据,1 ≤ N ≤ 100;
对于 50%的数据,1 ≤ N ≤ 10,000;
对于 100%的数据, 1 ≤ N ≤ 100,000, 1 ≤ R ≤ 50, 1 ≤ Q ≤ 2N,
0 ≤ s
1, s
2
, …, s
2N
≤ 108, 1 ≤ w
1
, w
2
, …, w
2N
≤ 108。
参考代码
#include <stdio.h>
#include <algorithm>
typedef struct PL
{
long d;
long s;
long w;
}P;
P p[2][1000000];
int comp(const void * a,const void * b)
{
P *pa = (P *)a;
P *pb = (P *)b;
if(pa->s < pb->s)
{
return 1;
}
else if(pa->s == pb->s && pa->d > pb->d)
{
return 1;
}
return -1;
}
int main()
{
long n,r,q,v,i,j,m,k,x1,x2;
scanf("%ld%ld%ld",&n,&r,&q);
k = n;
n = n * 2;
for(i = 1;i <= n;++ i)
{
scanf("%ld",&v);
p[1][i].s = v;
p[1][i].d = i;
}
for(i = 1;i <= n;++ i)
{
scanf("%ld",&v);
p[1][i].w = v;
}
qsort(p[1]+1,n,sizeof(p[1][1]),comp);
m = 1;
for(i = 1;i <= r;++ i)
{
for(j = 1;j <= k;++ j)
{
if(p[m][j * 2 - 1].w > p[m][j * 2].w)
{
p[m][j * 2 - 1].s ++;
P pt;
pt = p[m][j * 2];
p[m][j * 2] = p[m][j * 2 - 1];
p[m][j * 2 - 1] = pt;
}
else
{
p[m][j * 2].s ++;
}
}
x1 = 1;
x2 = 2;
for(j = 1;j <= n;++ j)
{
if(x1 < n && p[m][x1].s > p[m][x2].s ||
(p[m][x1].s == p[m][x2].s && p[m][x1].d < p[m][x2].d))
{
p[1 - m][j] = p[m][x1];
x1 = x1 + 2;
}
else if(x2 <= n)
{
p[1 - m][j] = p[m][x2];
x2 = x2 + 2;
}else
{
p[1 - m][j] = p[m][x1];
x1 = x1 + 2;
}
}
m = 1 - m;
}
printf("%ld\n",p[m][q].d);
return 0;
}。