“Wishare杯”南邮第九届大学生程序设计竞赛之现场赛 部分题解

本文主要是介绍“Wishare杯”南邮第九届大学生程序设计竞赛之现场赛 部分题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

A. 年轮

时间限制: 2000ms  内存限制: 65536KB

题目描述:

荒草丛生的青春

倒也过的安稳

代替你陪着我的

是年轮

数着一圈圈的年轮

我认真

将心事都封存

 

            现在就让我们数一数一圈圈的年轮吧,由于年轮不一定是标准的圆形,为了方便,我们规定一圈年轮一定是一个凸多边形,且任意两圈年轮必然不会有交点,现在把年轮上的所有可见的点全部投影到一个平面直角坐标系上,请问最多能数出多少圈年轮?注: 有些顶点可能不在任何一圈年轮上(凸多边形的定义:把一个多边形的所有边中,任意一条边向两方无限延长成为一直线时,其他各边都在此直线的同旁,这样的多边形就是凸多边形)。

 

输入:

            第一行为一个整数T(1<=T<=5)代表数据组数,每组数据第一行为一个整数n(3<=n<=1000),接下来n行,每行两个实数,代表一个点的坐标,坐标的绝对值不超过10^6。

 

输出:

            对于每组数据输出一个数字代表最多能数出的年轮圈数,如果一圈都数不出来输出”unlucky!” (引号不用输出)。

 

样例输入:

2

9

1.00 1.00

6.001.00

2.003.00

3.002.00

5.003.00

4.003.00

3.004.00

1.005.00

6.005.00

3

1.002.00

2.002.00

3.002.00

 

样例输出:

2

unlucky!

 

提示:

第一个样例中的两圈年轮为

{(1.00,1.00), (1.00, 5.00), (6.00, 1.00), (6.00, 5.00)}

{(2.00,3.00), (3.00, 2.00), (5.00, 3.00), (3.00, 4.00)}

 

题目分析:一层层求凸包

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 1e5;struct POINT {double x, y;int id;
}base, p[MAX], stk[MAX];
bool vis[MAX];
int n, top;double getDist(POINT p1, POINT p2) {return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
}double getCross(POINT p0, POINT p1, POINT p2) {return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}bool cmp(POINT p1, POINT p2) {if (getCross(base, p1, p2) == 0) {return getDist(base, p1) < getDist(base, p2);}return getCross(base, p1, p2) > 0;
}void getBase() {base.x = p[0].x;base.y = p[0].y;int pos = 0;for (int i = 1; i < n; i ++) {if (p[i].y < base.y || (p[i].y == base.y && p[i].x < base.x)) {base.x = p[i].x;base.y = p[i].y;pos = i;}}swap(p[0], p[pos]);
}bool getConvexHull() {if (n < 3) {return false;}sort(p + 1, p + n, cmp);  stk[0] = p[0];  stk[1] = p[1];  top = 1;  bool flag = false;for (int i = 2; i < n; i ++) {  while (top > 0 && getCross(stk[top - 1], stk[top], p[i]) < 0) {  top --;  }  if (top > 0 && getCross(stk[top - 1], stk[top], p[i]) > 0) {flag = true;}stk[++ top] = p[i];  }  if (top > 1 && flag) {for (int i = 0; i <= top; i ++) {vis[stk[i].id] = true;}return true;}return flag;
}void Delete() {int cnt = 0;for (int i = 0; i < n; i ++) {if (!vis[p[i].id]) {p[cnt ++] = p[i];}}n = cnt;memset(stk, 0, sizeof(stk));memset(vis, false, sizeof(vis));
}int main() {int T;scanf("%d", &T);while (T --) {scanf("%d", &n);memset(vis, false, sizeof(vis));for (int i = 0; i < n; i ++) {scanf("%lf %lf", &p[i].x, &p[i].y);p[i].id = i;}getBase();int ans = 0;while (getConvexHull()) {ans ++;Delete();getBase();} if (ans == 0) {printf("unlucky!\n");} else {printf("%d\n", ans);}}
}


E. 冷翻大师

时间限制:1000ms   内存限制:65536KB

题目描述:

            德州扑克AI冷扑大师完胜中国龙之队的事让南邮ACM协会的成员们热血沸腾,他们也想做一个AI程序,但由于德州扑克的规则太复杂,于是他们自己发明了一个翻牌游戏,一共有n张gain牌和m张loss牌,所有牌的反面均相同,现将这n+m张牌反面朝上随机打乱后放在桌上,每位玩家的初始得分都是0且均知道gain牌和loss牌的数量,一次可随意抽取若干张牌,也可以选择一张不抽,抽到gain牌得1分,抽到loss牌扣1分,选完一轮后记下分数作为该玩家本次游戏的最终得分,然后继续将这n+m张牌打乱换下一个玩家抽,所有玩家都抽完,谁得分最高谁获胜。该AI程序将被命名为冷翻大师,完成冷翻大师的编写前,请你帮成员们计算出在玩家每次都使用最优策略的情况下,一轮抽牌的得分期望。(设X1, X2, …, Xn为离散型随机变量,P(X1), P(X2), …, P(Xn)为变量对应事件发生的概率,则期望E(X)=X1*P(X1)+X2*P(X2)+…+Xn*P(Xn) )

 

输入:

            第一行为一个整数T代表数据组数,每组数据包含两个整数n和m

(1<=T<=5,0 <= n, m <= 1000)

 

输出:

            对于每组数据输出一个数字代表得分期望,要求保留4位小数(四舍五入)

 

样例输入:

3

1 0

1 1

0 1

 

样例输出:

1.0000

0.5000

0.0000

 

提示:

第二组数据中若先抽到gain牌,得1分,因知道还剩一张loss,必不会继续抽,相反如果先抽到loss,必会去抽第二次,总得分为0,所以E=0.5*1+0.5*0=0.5


题目分析:简单期望dp,dp[i][j],还剩i张gain和j张loss的得分期望,转移方程不难推,见程序

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int const MAX = 1e3 + 5;
double dp[MAX][MAX];int main() {int T, n, m;scanf("%d", &T);for (int ca = 1; ca <= T; ca ++) {memset(dp, 0, sizeof(dp));scanf("%d %d", &n, &m);for (int i = 0; i <= n; i ++) {for (int j = 0; j <= m; j ++) {if (i == 0) {continue;} else if (j == 0) {dp[i][j] = dp[i - 1][j] + 1;} else {double gain = (dp[i - 1][j] + 1) * ((1.0 * i) / (1.0 * (i + j)));double loss = (dp[i][j - 1] - 1) * ((1.0 * j) / (1.0 * (i + j)));dp[i][j] = max(dp[i][j], gain + loss);}}}printf("%.4f\n", dp[n][m]);}
}


F.人民的名义

时间限制: 3000ms   内存限制:65536KB

题目描述:

提前给大家剧透一下”人民的名义的大结局”,检察官候亮平收到一封匿名信,信中暗含了所有贪官的名字,但是为了保密,名字没有直接写出来,信中给的是一个语料库和若干行字符串,每行字符串中分别暗含了一个贪官的名字,你需要根据语料库通过分词来解析字符串中暗含的信息,比如语料库{“gao”,”yu”,”liang”,”li”,”ang”},字符串为gaoyuliang,所有被解析出来的内容为”gaoyu liang”和”gao yu li ang”,现在请你帮助检察官侯亮平解析这封匿名信。

 

输入:

每个测试文件仅包含一组数据,输入第一行为一个整数n(1 <= n <= 1000),代表语料库字符串个数,第二行输入n个互不相同的字符串代表语料库(最长的字符串的长度不会超过30),第三行为一个要被解析的字符串(长度不超过100),语料库和待解析的字符串均只含小写字母。

 

输出:

对每个要被解析的字符串,解析结果的每两个单词或拼音间用一个空格隔开,将解析的结果作为一个整体(含空格)按照字典序从小到大输出(字典序排序:两个字符串依次按照对应位的Ascii码值比较,如果首字符相同则比较第二个,第二个相同则比较第三个,依次类推,比如b>a,ab>aa,aab>aaa),若无法解析出任何信息,输出”nothing!”(引号不用输出)

 

样例输入:

5

gao yuliang li ang

gaoyuliang

 

样例输出:

gao yuli ang

gao yuliang

 

题目分析:就是让分词,DFS搞,预处理记录一下以某个位置结尾的单词,然后搜一搜就可以了,也可以用trie维护

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <set>
#include <string>
#include <iostream>
using namespace std;vector<string> dp[200];void DFS(int pos, vector<string>& ans, vector<string>& tmp) {if (pos == 0) {int tmpSize = tmp.size();string cur = tmp[tmpSize - 1];for (int i = tmpSize - 2; i >= 0; i --) {cur += " ";cur += tmp[i];}ans.push_back(cur);return;}int sz = dp[pos].size();if (sz) {for (int i = 0; i < sz; i ++) {tmp.push_back(dp[pos][i]);DFS(pos - dp[pos][i].size(), ans, tmp);tmp.pop_back();}}
}vector<string> wordBreak(string s, vector<string> wordDict) {vector<string> ans;int len = s.size();dp[0].push_back("");for (int st = 0; st < len; st ++) {if (dp[st].size() > 0) {for (int i = 0; i < wordDict.size(); i ++) {string cur = wordDict[i];int ed = st + cur.size();if (ed <= len) {if (s.substr(st, ed - st) == cur) {dp[ed].push_back(cur);}}}}}if (dp[len].size() == 0) {return ans;}vector<string> tmp;DFS(len, ans, tmp);return ans;
}vector<string> vt;
string str;
int m;int main() {scanf("%d", &m);string tmp;for (int i = 0; i < m; i ++) {cin >> tmp;vt.push_back(tmp);}cin >> str;int len =str.length();vector<string> ans = wordBreak(str, vt);if (ans.size() == 0) {printf("nothing!\n");} else {sort(ans.begin(), ans.end());for (int i = 0; i < ans.size(); i ++) {cout << ans[i] << endl;}}
}


G. 中韩大战之人浪

时间限制:2000ms        内存限制65536KB

题目描述:

            世界杯预选赛亚洲区12强赛,中国队1:0领先韩国队的时候全场的中国球迷都沸腾了,他们玩起了人浪,所谓人浪就是观众以排为单位依照顺序起立举手再坐下,呈现类似波浪的效果,为简单起见,我们称某个位置比两边都高的为浪尖。已知体育场有n排座位,每排可以坐m个人,现给出某一时刻各排人浪的状态,请计算出最多的浪尖个数及浪尖最多的排号。假设足球场的观众席是圆形的且比赛时座无虚席。

 

输入:

            每个测试文件仅包含一组数据,输入第一行为两个整数n (1 <= n <= 1000)和m (3 <= m <=1000),接下来输入共n行,每行m个实数,第i行的第j个数字h[i][j]表示第i排的第j个观众当前的高度,(1.00<=h[i][j] <= 6.00)

 

输出:

            输出两个数字,分别代表最多的浪尖个数及其所对应的排号,最多浪尖个数不止一排的时候,输出总高度最高那排的排号,若总高度也相同,则输出最大的排号,若这n排一个浪尖都没有,则输出”unbelievable!” (引号不用输出)。

 

样例输入:

2 4

1.002.00 3.00 4.00

2.004.00 1.00 3.00

 

样例输出:

2 2

 

提示:

本题数据量较大,输入请使用scanf


题目分析:C语言课后作业难度,输出讨论情况较多

#include <cstdio>
int const MAX = 1005;
double a[MAX][MAX];int main() {int n, m, ans = 0, id = 0;double maSum = 0;scanf("%d %d", &n, &m);for (int i = 1; i <= n; i ++) {int cnt = 0;double sum = 0;for (int j = 1; j <= m; j ++) {scanf("%lf", &a[i][j]);sum += a[i][j];}if (a[i][1] > a[i][m] && a[i][1] > a[i][2]) {cnt ++;}for (int j = 2; j < m; j ++) {if (a[i][j] > a[i][j - 1] && a[i][j] > a[i][j + 1]) {cnt ++;}}if (a[i][m] > a[i][1] && a[i][m] > a[i][m - 1]) {cnt ++;}if (cnt > ans) {ans = cnt;id = i;if (sum > maSum) {maSum = sum;}} else if (cnt == ans && sum >= maSum) {maSum = sum;id = i;}}if (ans == 0) {printf("unbelievable!\n");} else {printf("%d %d\n", ans, id);}
}


这篇关于“Wishare杯”南邮第九届大学生程序设计竞赛之现场赛 部分题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/829522

相关文章

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析