HPU暑期集训积分赛3
A题:
Math Problem
Description
求:\sum_{i=1}^n \lfloor \frac {a_i}{k} \rfloor∑i=1n⌊kai⌋
ps: \lfloor x \rfloor⌊x⌋ 表示x向下取整
Input
第一行一个整数TT表示测试组数。(1 \leq T \leq 10)(1≤T≤10)
第二行一个nn和kk,nn表示序列a的长度。( 1 \leq n ,k\leq 1e6)(1≤n,k≤1e6)
第三行n个整数表示a_iai ( 0 \leq a_i \leq 1e6)(0≤ai≤1e6)
Output
每组数据输出题目描述的求和值。
Sample Input 1
2 2 1 3 5 3 2 1 2 3
Sample Output 1
8 2
Source
lzs
思路:
签到题
代码:
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
const int maxn =(int)1e6 + 10;
int a[maxn];
int main()
{int t;scanf("%d",&t);while (t--){ll ans = 0;int n,k;scanf("%d %d",&n,&k);for (int i = 0 ;i < n;i ++){scanf("%d",&a[i]);ans += a[i] / k;}printf("%lld\n",ans);}return 0;
}
C题:
Multivariate function
Description
Input
第一行一个整数T,表示T组测试数据 (1\leq T \leq 10)(1≤T≤10).
每组数据第一行一个整数n (4 \leq n \leq 1000)(4≤n≤1000).
第二行 n个浮点数: x_{1},x_{2}...x_{n}x1,x2...xn,(1 \leq x_{i} \leq 1000000)(1≤xi≤1000000).
Output
输出最大值 y,保留三位小数.
Sample Input 1
2 4 1.0 2.0 3.0 4.0 5 1.6 2.6 7.1 2.3 2.6
Sample Output 1
0.167 1.530
Source
SDP
思路:
这道题本身并不是很难,只是被一堆数字吓到了,对于公式 y = { xj * xp - xi * xk} / { xk * ( xi + xj) } ,我们可以将其化简成
y = xj * (xp / xk) / (xi + xj ) - xi / (xi + xj ),这个式子仔细搞搞不难发现由于i < j < p < k,所以我们可以用O(n^2)的复杂度暴力预处理出
c = xp / xk,于是xp / xk就变成了一个常数,式子又变成了y = (c * xj - xi ) / (xi + xj ) ,数据量是1e3,接下来再用一个O(n^2)的复杂度得到max( y ),完全可以接受;
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
double f[maxn];
double a[maxn]; //a数组存预处理的结果
int main()
{int t;scanf("%d",&t);while (t --){memset(a,0,sizeof(a));int n;scanf("%d",&n);for (int i = 1;i <= n;i ++)scanf("%lf",&f[i]);for (int i = n - 1;i >= 1;i --)for (int j = n;j > i;j --){a[i] = max(max(a[i],a[i + 1]),f[i] / f[j]);}double ans = 0;for (int i = 1;i <= n - 3;i ++)for (int j = i + 1;j <= n - 2;j ++){double res = f[j] / (f[i] + f[j]) * (a[j + 1]) - f[i] / (f[i] + f[j]);ans = max(ans,res);}printf("%.3lf\n",ans);}return 0;
}
D题:
Longest Increasing Subsequence
Description
给出一组长度为nn的序列,a_1,a_2,a_3,a_4...a_na1,a2,a3,a4...an, 求出这个序列长度为kk的严格递增子序列的个数
Input
第一行输入TT组数据 T (0\leq T\leq 10)T(0≤T≤10)
第二行输入序列大小n(1\leq n \leq100)n(1≤n≤100),长度k(1\leq k \leq n)k(1≤k≤n)
第三行输入nn个数字a_i(0\leq a_i \leq 1e9)ai(0≤ai≤1e9)
Output
数据规模很大, 答案请对1e9+71e9+7取模
Sample Input 1
2 3 2 1 2 2 3 2 1 2 3
Sample Output 1
2 3
思路:
这道题emmmmm,还不是太懂,一道LIS
代码:
#include<bits/stdc++.h>
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
const int mod = (int)1e9 + 7;
const int maxn = 110;
int a[maxn],dp[maxn][maxn];
int main()
{int t;scanf("%d",&t);while (t --){mem(dp);int n,k;scanf("%d %d",&n,&k);for (int i = 0;i < n;i ++)scanf("%d",&a[i]);for (int i = 0;i < n;i ++)dp[i][1] = 1;for (int i = 0;i < n;i ++)for (int j = 2;j <= i + 1;j ++)for (int p = 0;p < i;p ++){if (a[p] < a[i])dp[i][j] = (dp[i][j] + dp[p][j - 1]) % mod;}int ans = 0;for (int i = 0;i < n;i ++)ans = (ans + dp[i][k]) % mod;printf("%d\n",ans);}return 0;
}
E题:
玩游戏
Description
zxy和wfy用几堆石子在做游戏。偶数堆石子排成一行,每堆都有正整数颗石子 a[i]a[i] 。游戏以谁手中的石子最多来决出胜负。石子的总数是奇数,所以没有平局。zxy和wfy轮流进行,wfy先开始。 每回合,玩家从一行的开始或结束处取走整堆石头。 这种情况一直持续到没有更多的石子堆为止,此时手中石子最多的玩家获胜。假设zxy和wfy都发挥出最佳水平,当zxy赢得比赛时输出“zxy” ,当wfy赢得比赛时输出“wfy”。
Input
有T组输入,每个输入后有一个nn,在nn后有nn个数字,a_1,a_2....a_{n}a1,a2....an。
n的范围是1\leq n\leq1e^51≤n≤1e5,1\leq a_i\leq1e^51≤ai≤1e5.
Output
输出胜利者的名字"zxy"或者"wfy"
Sample Input 1
1 4 5 3 4 5
Sample Output 1
wfy
Hint
wfy先开始,只能拿前 5 颗或后 5 颗石子 。
假设他取了前 5 颗,这一行就变成了 [3,4,5] 。
如果zxy拿走前 3 颗,那么剩下的是 [4,5],wfy拿走后 5 颗赢得 10 分。
如果zxy拿走后 5 颗,那么剩下的是 [3,4],wfy拿走后 4 颗赢得 9 分。
这表明,取前 5 颗石子对wfy来说是一个胜利的举动,所以我们输出wfy 。
思路:
这道题是瞎推的,场上没有看到偶数堆,推出了偶数堆先拿的必,应该是数据有问题,我明明分了偶数堆必胜的,就是没过,有点亏,总之wfy是必胜的,只要无脑输出wfy就行了
代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{int t;scanf("%d",&t);while (t--){int n,x;scanf("%d",&n);for (int i = 0;i < n;i ++)scanf("%d",&x);printf("wfy\n");}return 0;
}
F题:
辞树的肥宅快乐水
Description
又到了基情四射的夏天,大家出去约妹子,而肥宅辞树只想宅在机房喝肥宅快乐水。辞树一下子买了n瓶肥宅快乐水。已知他一天里至少喝掉一瓶肥宅水且他是一口干掉一整瓶。(肥宅Orz)他想要知道自己一共有多少种喝肥宅水的方案。两种方案被认为是不同的,当且仅当辞树买的这些肥宅水能喝的天数不同,或者存在一天两种方案喝的肥宅水瓶数不同。
Input
第一行输入一个正整数T,代表有T组数据(0<T<11)(0<T<11)每组数据有一个正整数n,代表辞树买了n瓶肥宅快乐水。(0<n<10^8)(0<n<108)
Output
对于每组数据,输出一行,将方案数用二进制表示输出。
Sample Input 1
1 3
Sample Output 1
100
思路:
多写几组数据很容易就会发现方案数就是2^(n - 1),换成二进制就无脑输出1加(n - 1)个0就行了,由于担心会超时,我就分块输出了,其实没必要
代码:
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define mem(a) memset(a,'0',sizeof(a))
using namespace std;
char str[10000];
int main()
{int t;scanf("%d",&t);while (t--){mem(str);int n;scanf("%d",&n);n --;printf("1");while (n > 10000){printf("%s",str);n -= 10000;}while (n--)putchar('0');putchar('\n');}
}
G题:
From The New WorldⅠ
Description
千年之后,「新世界」的孩子们被彻底地控制和管束著,不合适的记忆被消去,被认为有问题的孩子如同不良产品般被处理......
Saki和她的小伙伴们在完人学校迎来了第一个学期考试,考试规则如下:要求你使用自己的咒力对规定的图画进行有限次的念写,你需要找到其中的咒术节点并尽可能的削弱它的咒力值,最后输出最长的咒术节点的长度.
请你用程序的方式来完成考试,可把图画抽象为一段具体的序列,咒术节点可看为特定的数值,特定的数值连续出现越多咒术节点的咒力值越大.每次操作只能将要修改的值修改为自己的咒力值.(即:给定长度为n的序列,用给出的自身咒力值p替换序列中k个数,使规定的数值x连续出现的最长长度最短,输出最终最长的x的连续的长度.保证p! = x)
Input
多组输入,请处理到文件结束
第一行依次输入n,p,x,kn,p,x,k. n表示序列的长度,p表示自身咒力值,x表示咒术节点的值,k表示规定修改次数.
(1 <= n <= 100000; 1 <= p <= 20; 0 <= x <= 100000; 0 <= k <= n)(1<=n<=100000;1<=p<=20;0<=x<=100000;0<=k<=n)
第二行输入n个ai (0 <= ai <= 100000000)ai(0<=ai<=100000000)表示序列n个元素的值
Output
每行输出咒术节点连续出现最大长度
Sample Input 1
7 3 5 3 8 2 5 5 5 5 5
Sample Output 1
1
Hint
样例解释:修改后的序列为8 2 5 3 3 3 5 最大长度为1
思路:
一道很经典的二分,预处理出连续的x的个数,对于每个长为n的连续的x,如果想要让它变成长为k则需要n / (k + 1)个p
于是二分长度
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = (int)1e5 + 10;
int a[maxn];
int num[maxn],pos;
int n,p,x,k;
bool judge(int n)
{int cnt = 0;for (int i = 0;i < pos;i ++)cnt += num[i] / (n + 1);if (cnt <= k)return 1;return 0;
}
int main()
{while (~scanf("%d %d %d %d",&n,&p,&x,&k)){pos = 0;int cnt = 0,m = 0,sum = 0;scanf("%d",&a[1]);if (a[1] == x) cnt = sum = 1;for (int i = 2;i <= n;i ++){scanf("%d",&a[i]);if (a[i] == x)cnt ++,sum ++;else{if (cnt){num[pos ++] = cnt;m = max(cnt,m);}cnt = 0;}}if (cnt) num[pos ++] = cnt;m = max(cnt,m);int l = 0,r = m,mid;while (l <= r){mid = (l + r) >> 1;if (judge(mid)) r = mid - 1;else l = mid + 1;}printf("%d\n",l);}return 0;
}
H题:
真,签到题
Description
A国的n个作战通信基站大部分被C国的特种部队破坏,基站编号1到n,只剩下编号为a和b的通信基站完好,为了快速恢复通信,A国派出zzx和fk两位工程师去修复,A国的通信基站有一个特殊隐蔽的备用系统,只有让两个完好的通信基站向编号为x的基站发送信号,x是这两个完好基站编号的和或者差的绝对值,该被破坏的基站的备用系统才会被激活,工程师才能恢复被破坏的基站,假设zzx工程师先到达可修复的基站进行修复,接着fk去修复下一个,两人轮流修复,问谁会修复最后一个可修复的基站.
初始:zzx已经修复aa,接着fk已经修复bb,且a!=ba!=b.
Input
输入n,a,bn,a,b三个整数,代表基站的总数nn和剩下的完好的两个基站的编号a,ba,b.
1 < n <= 1e5,1 <= a,b <= n1<n<=1e5,1<=a,b<=n,a!=ba!=b 处理到文件结束
Output
若zzx修复最后一个,输出 zzx,否则输出fk
Sample Input 1
5 1 4 10 3 7 11 4 8
Sample Output 1
zzx fk fk
思路:
对于已经修好的a和b基站,我们可以通过a和b修出最小为c = gcd(a,b)的基站,其他的只要是c的倍数,就一定能够修好,那么总共可以修的 基站个数就是n / c (包括a,b),于是如果这个数是奇数,那么就是zzx修好最后一个,否则输出fx
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int gcd(int a,int b)
{return b ? gcd(b,a % b) : a;
}
int main()
{int n,a,b;while (~scanf("%d %d %d",&n,&a,&b)){int x = gcd(a,b);if (n / x % 2 == 0)printf("fk\n");elseprintf("zzx\n");}return 0;
}
I 题:
阶乘之和
Description
对于整数pp,给出以下定义
p=x_{1}!+x_{2}!+x_{3}!+...+x_{q}!(x_{i}<x_{j}for\ all\ i<j )p=x1!+x2!+x3!+...+xq!(xi<xjfor all i<j)且x_{i} \neq 0xi≠0
((注释:p等于多个数的阶乘和,并且x_{1},x_{2},x_{3},...,x_{q}x1,x2,x3,...,xq为不相等的任意正整数,即组成p的阶乘不重复使用))
给定两个整数x,y,判断二者是否能满足以上定义。若二者都满足定义,设x由k_{1}k1个数的阶乘和组成,y由k_{2}k2个数的阶乘和组成,若k_{1}=k_{2}k1=k2,按下述输出格式输出二者的定义形式((输出时,阶乘按递增形式输出,例如:7=1!+3!))。
Input
第一行输入一个整数T,代表T组测试数据。(1\leq T \leq 10000)(1≤T≤10000)
接下来T行,每行包含两个整数x,y。(1\leq x,y \leq 10^{18})(1≤x,y≤1018)
Output
对于每组x,y输出包含两部分:
①如果二者都满足以上定义,输出“SEYES”;如果只有其一满足以上定义,输出“YNEOS”;如果二者都不满足以上定义,则输出“ONO”。
②当x,y都满足以上定义且k_{1}=k_{2}k1=k2时,输出二者的定义形式。否者输出“dWvWb”。
Sample Input 1
4 7 7 1 2 4 2 4 4
Sample Output 1
Case 1:SEYES 7=1!+3! 7=1!+3! Case 2:SEYES 1=1! 2=2! Case 3:YNEOS dWvWb Case 4:ONO dWvWb
思路:
这题很简单,打表加暴力就水过了,就除了写着比较麻烦罢了
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[50],b[20];
void init()
{for (int i = 1;i <= 18;i ++){ll ans = 1;for (int j = 1;j <= i;j ++)ans *= j;a[i] = ans;}
}int solve(ll x)
{int pos;pos = 0;int flag = 1,i;while (x > 0){for (i = 18;i >= 1;i --){if (x > a[i]){b[pos ++] = i;x -= a[i];}else if (x == a[i]){b[pos ++] = i;x -= a[i];break;}}if (i == 0){flag = 0;break;}}if (flag)return pos;elsereturn flag;
}
int main()
{init();int t,kase = 0;scanf("%d",&t);while ( t--){kase ++;ll n,m;scanf("%lld %lld",&n,&m);int f1 = solve(m);int f2 = solve(n);if (f1 && f2){printf("Case %d:SEYES\n",kase);if (solve(n) == solve(m)){f1 = solve(n);printf("%lld=%d!",n,b[f1 - 1]); for (int i = f1 - 2;i >= 0;i --)printf("+%d!",b[i]);putchar('\n');f2 = solve(m);printf("%lld=%d!",m,b[f2 - 1]);for (int i = f2 - 2;i >= 0;i --)printf("+%d!",b[i]);putchar('\n');}else printf("dWvWb\n");}else if(!f1 && !f2){printf("Case %d:ONO\n",kase);printf("dWvWb\n");}else{printf("Case %d:YNEOS\n",kase);printf("dWvWb\n");}}return 0;
}
J题:
过河问题
Description
在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。
Input
多组数据。
每组测试数据的第一行是一个整数N(从1到1000,包括1和1000)表示共有N个人要过河
每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(Si 小于等于 100,大于等于1)
Output
输出所有人都过河需要用的最少时间。
Sample Input 1
4
1 2 5 10
Sample Output 1
17
Source
丁金峰
思路:
这道题主要是样例很难想,首先对这n个人花费的时间升序排序,现在我们假设要过河的n个人分别是a,b,c..........d,e,f,那么最后两个费时最多的人过河所要花费的时间可以有两种方法,1、b + a + f + b(先让a,b一起过河,再让a回来,e和f一起过河,b回来,这里a,b还要回来是因为还要带其他人)2、f + a + e + a;剩下的就很简单了,我们只需要两个人两个人的过河(这两种过河方式不理解的可以参考样例),时间就是加上他们过河用的最少的时间,最后再加上剩下的前两个人或前三个人要过河用的时间;
代码:
#include<bits/stdc++.h>
using namespace std;
int a[1005];
int main()
{int n;while(~scanf("%d",&n)){for (int i = 0;i < n;i ++)scanf("%d",&a[i]);sort(a,a + n);int ans = 0,i; for (i = n - 1;i >= 3;i -= 2)ans += min(a[1] + a[0] + a[i] + a[1],a[0] + a[0] + a[i] + a[i - 1]);if (i == 1)ans += a[1];elseans += a[0] + a[1] + a[2];printf("%d\n",ans);}return 0;
}
HPU暑期集训积分赛3相关推荐
- 暑期集训5:并查集 线段树 练习题G: HDU - 1754
2018学校暑期集训第五天--并查集 线段树 练习题G -- HDU - 1754 I Hate It 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让 ...
- 暑期集训5:并查集 线段树 练习题F: HDU - 1166
2018学校暑期集训第五天--并查集 线段树 练习题F -- HDU - 1166 敌兵布阵 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A ...
- 暑期集训5:并查集 线段树 练习题B: HDU - 1213
2018学校暑期集训第五天--并查集 线段树 练习题B -- HDU - 1213 How Many Tables Today is Ignatius' birthday. He invites ...
- 暑期集训5:并查集 线段树 练习题A: HDU - 1232
2018学校暑期集训第五天--并查集 线段树 练习题A -- HDU - 1232 畅通工程 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅 ...
- 暑期集训4:栈,树,优先队列 例 : UVA - 514
2018学校暑期集训第四天--栈,树,优先队列 例题 -- UVA - 514 Rails There is a famous railway station in PopPush City. ...
- 暑期集训3:几何基础 练习题H: POJ - 2456
2018学校暑期集训第三天--几何基础 练习题H -- POJ - 2456 Aggressive cows Farmer John has built a new long barn, wit ...
- 暑期集训3:几何基础 练习题G: HDU - 1052
2018学校暑期集训第三天--几何基础 练习题G -- HDU - 1052 (昨天加练题) Tian Ji -- The Horse Racing Here is a famous sto ...
- 暑期集训3:几何基础 练习题F: CodeForces - 1007A
2018学校暑期集训第三天--几何基础 练习题F -- CodeForces - 1007A Reorder the Array You are given an array of intege ...
- 暑期集训3:几何基础 练习题D: HDU - 2036
2018学校暑期集训第三天--几何基础 练习题D -- HDU - 2036 改革春风吹满地 " 改革春风吹满地, 不会AC没关系; 实在不行回老家, 还有一亩三分地. 谢谢 ...
最新文章
- 在微服务架构下基于 Prometheus 构建一体化监控平台的最佳实践
- IntelliJ IDEA 最常用配置,应用、永久激活
- python读txt转array_np.array和txt文件的转换
- 简述用决策表设计测试用例的步骤_决策表快速入门
- 替换python字典中的key值
- pandas中如何选取某几列_pandas 选取行和列数据的方法
- (转)KMP算法原理讲解及模板C实现
- web 日志分析工具 awstats 简单安装
- C的|、||、、、异或、~
- 计算机用英语表示方法有哪些,在计算机领域中,通常用英文单词“bit”来表示( )...
- jquery ui datepicker 只能选今天以后的日期
- 固态硬盘 linux 文件系统,SSD是否需要使用特别的文件系统?
- 信息学奥赛一本通(1037:计算2的幂)
- mysql1241 错误,[Err] 1241 - Operand should contain 1 column(s)错误解析
- js设置css行内样式
- 计量经济学知识点及案例整理
- jdk7与jdk8 如何相互切换
- 收费系统对接微信公账号流程
- 重装系统要钱吗?电脑重装系统需要多少钱?
- DataType--类型基础
热门文章
- 什么是品牌营销?学会正确推广您的业务
- 一览群智的“锤子”、“钉子”和“右手”
- ssm+java计算机毕业设计职业高中智慧教学系统5vuz6(程序+lw+源码+远程部署)
- Visual Studio 2010工程目录下的ipch文件夹和.sdf文件
- 抖音直播公会怎么入驻呢?
- C语言--判断一个数的奇偶
- 【瑞模网】今天我们来谈谈【像素流送】到底是什么??
- Qt编写物联网管理平台38-多种数据库支持
- 电线直径对照表_电缆直径对照表
- java 钱币的单位转换