因为有很多队已经克隆过了
所以在VJ上可以看到其他队伍的排名情况和交题记录
刚开始几分钟 就有队伍过了F题
果断看F题 确实是个水题
HDU6292 赛题分析
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 1882 Accepted Submission(s): 869
Problem Description
著名出题人小Q每次比赛后都会写一份《赛题分析》,包含比赛概况、每题的参考算法以及一些统计数值。
对于一道题来说,小Q会统计最短的验题人代码长度(Shortest judge solution)以及赛内参赛队伍最短的AC代码长度(Shortest team solution)。
统计验题人代码长度比较容易,因为验题人最多也不会超过20个。但是统计选手代码长度就不容易了,因为大赛区动辄三四百支队伍。
请写一个程序,帮助小Q统计最短代码长度。
Input
第一行包含一个正整数T(1≤T≤13),表示赛题数量。
每道题第一行包含两个整数n,m(2≤n≤20,0≤m≤500),分别表示验题人数量以及AC了该题的队伍数量。
第二行包含n个正整数a1,a2,...,an(50≤ai≤65536),依次表示每个验题人的代码字节数。
第三行包含m个正整数b1,b2,...,bn(50≤bi≤65536),依次表示每支AC队伍的代码字节数。若m=0则该行为空行。
Output
对于第i(1≤i≤T)道题,输出三行,第一行输出Problem x:,其中x=i+1000。
第二行输出Shortest judge solution: y bytes.,其中y表示最短的验题人代码字节数。
第三行输出Shortest team solution: z bytes.,其中z表示最短的选手代码字节数,若不存在请输出N/A。
注意:间隔都是一个空格。
Sample Input
2 3 2 3627 1460 5288 2365 2671 2 0 5510 7682
Sample Output
Problem 1001:
Shortest judge solution: 1460 bytes.
Shortest team solution: 2365 bytes.
Problem 1002:
Shortest judge solution: 5510 bytes.
Shortest team solution: N/A bytes.
思路:
暴力寻找最小值即可
注意判断 m 输入为 0 时 不输出最小值 而是 N/A
(我因为少了一个句号没发现 而WA了好多发 还好队友大白也写了一遍就AC了)
代码
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
int main()
{
int t, n, m, x, y;
scanf("%d", &t);
for (int i = 1; i <= t; i++) {
scanf("%d%d", &n, &m);
printf("Problem %d:\n", 1000 + i);
scanf("%d", &x);
int minn = x;
for (int j = 1; j < n; j++) {
scanf("%d", &x);
minn = min(minn, x);
}
printf("Shortest judge solution: %d bytes.\n", minn);
if (m > 0) {
scanf("%d", &y);
int mi = y;
for (int k = 1; k < m; k++) {
scanf("%d", &y);
mi = min(mi, y);
}
printf("Shortest team solution: %d bytes.\n", mi);
} else {
printf("Shortest team solution: N/A bytes.\n");
}
}
return 0;
}
PS: 这里不用long long ,数据不算很大……
与此同时 Alone 看了K题
我没仔细看
HDU6297 CCPC直播
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 2128 Accepted Submission(s): 847
Problem Description
在比特镇举行的中国大学生程序设计竞赛CCPC(China Collegiate Programming Contest)开始啦!这次比赛中加入了现场视频直播,而在直播屏幕的左下角,会显示评测队列。
比特镇的科技水平并不发达,直播分辨率并不高。准确地说,每个评测记录将被显示在1行38列的像素格上。一条评测记录由4个部分组成,从左往右依次为排名(3像素),队名(16像素),题号(4像素),评测情况(12像素)。相邻两个部分之间由1像素的分隔线|分开。其中,排名右对齐显示,队名左对齐显示,长度不足时用空格补齐。题号一定是4位正整数,因此恰好占据4像素。评测情况则比较复杂,它由两侧的括号[]以及中间10像素组成。
样例第一行表示排名第19的队伍qqqqq_University提交了题目1001,已经通过了30%的测试点,故左对齐显示3个X。
样例第二行表示排名第125的队伍quailty_U_2提交了题目1002,评测结果为WA,故居中显示WA,左边留4像素空格。
样例第三行需要居中显示TLE,左边同样留4像素空格。
样例第四行这支队伍是全场第一个通过1003的,故在AC后加上字符∗来特殊标注。
请写一个程序,对于每条评测记录产生直播信息。
Input
第一行包含一个正整数T(1≤T≤1000),表示评测记录的数量。
接下来T行,每行首先是一个正整数rank(1≤rank≤400),表示队伍的排名。
接下来一个长度不超过16的字符串S,表示队名,S仅由大小写字母、数字以及下划线"_"组成。
接下来一个正整数prob(1001≤prob≤1013),表示题号。
接下来一个字符串T(T∈{Running,AC,WA,TLE,MLE,RTE,CE,OLE,PE,FB}),表示评测状态,除Running外均表示评测结束。若为Running,则还会输入一个正整数p(1≤p≤9),表示已经通过了p×10%的测试点。若为FB,则表示全场第一个通过该题,应显示AC∗。
Output
对于每条评测记录,按要求输出一行一个长度为38的字符串,即直播显示效果。
Sample Input
5
19 qqqqq_University 1001 Running 3
125 quailty_U_2 1002 WA
4 quailty_U_3 1003 TLE
1 quailty_U_4 1003 FB
2 qqqqq 1001 AC
Sample Output
19|qqqqq_University|1001|[XXX ]
125|quailty_U_2 |1002|[ WA ]
4|quailty_U_3 |1003|[ TLE ]
1|quailty_U_4 |1003|[ AC* ]
2|qqqqq |1001|[ AC ]

以图片为准(不知道为啥 复制过来就长得不一样了emm
刚刚看了题意 大致为:给出 T 组数据 要求按照格式输出一遍
控制输出就好了……
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
int main()
{
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
char award[5],name[20],prob[5],status[10];
while(t--)
{
scanf("%s",award);
scanf("%s",name);
scanf("%s",prob);
scanf("%s",status);
if(strlen(award)<3)
{
for(int i=0;i<3-strlen(award);i++)
printf(" ");
}
printf("%s|",award);
printf("%s",name);
if(strlen(name)<16)
{
for(int i=0;i<16-strlen(name);i++)
printf(" ");
}
printf("|%s|[",prob);
if(status[1]=='u')
{
int p;
scanf("%d",&p);
for(int i=0;i<p;i++)
printf("X");
if(p<10)
for(int i=0;i<10-p;i++)
printf(" ");
printf("]\n");
}
else
{
if(status[0]=='F')
printf(" AC* ]\n");
else if(status[0]=='A'||status[0]=='W'||status[0]=='P'||status[0]=='C')
printf(" %s ]\n",status);
else
printf(" %s ]\n",status);
}
}
return 0;
接着看了H题
也是Alone做的
一个字符串比较的问题
HDU6294 SA-IS后缀数组
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 2421 Accepted Submission(s): 689
Problem Description
小Q最近阅读了SA-IS算法在线性时间内构造后缀数组的相关论文,面对任何字符串题,都可以想出线性时间的算法。
小T在经历过二分图匹配事件后,再也不相信小Q所说的话。面对小Q,小T又给出了一道字符串题:
给定一个长度为n的小写字符串S[1..n],设sufi表示以i 为开始的后缀,即S[i..n]。
记|X|为字符串X的长度,对于两个字符串X和Y,定义X的字典序比Y小,当且仅当存在非负整数k(k≤min(|X|,|Y|))使得X的前k个字符与Y的前 k个字符对应相同,并且要么满足|X|=k且|Y|>k,要么满足k<min(|X|,|Y|)且X的第k+1个字符比Y的第k+1个字符小。例如aa的字典序比aaa小,ab的字典序比ba小。
请对每个i(1≤i<n),判断sufi和sufi+1的字典序大小关系。
只会吹牛的小Q又不会做了,所以他再一次向你紧急求助。请写一个程序,判断相邻两个后缀的大小关系。
Input
第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。
每组数据第一行包含一个正整数n(2≤n≤1000000),表示字符串S的长度。
第二行包含一个长度为n的小写字符串S。
Output
对于每组数据,输出一行n−1个字符,第i个字符表示sufi和sufi+1的大小关系,若sufi<sufi+1,输出<,否则输出>,显然不存在相等关系。
Sample Input
1
17
quailtyacmbestacm
Sample Output
<><<<<><<><<<><<
思路:
从第一个字符开始比较 如果s[i] < s[i+1] 则是 < 否则是 >
如果是 s[i] == s[i+1] 就继续往后找不相等的字符 再次判断
中间一段相等的字符比较的结果由 第一个不相等的字符决定
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e7+5;
char s[maxn],ans[maxn];
int main()
{
//freopen("in.txt","r",stdin);
int t,n;
scanf("%d",&t);
while(t--)
{
memset(ans,0,sizeof(ans));
scanf("%d",&n);
scanf("%s",s);
int len=0,pos=0;
for(int i=0;i<n-1;i++)
{
pos=0;
if(s[i]<s[i+1])
ans[len++]='<';
else if(s[i]>s[i+1])
ans[len++]='>';
else
{
pos=i;
while(s[i]==s[i+1])
i++;
//printf("*%d\n",i);
if(s[i]<s[i+1])
{
for(int j=pos;j<=i;j++)
ans[len++]='<';
}
else if(s[i]>s[i+1])
{
for(int j=pos;j<=i;j++)
ans[len++]='>';
}
//printf("*%d\n",len);
if(i==n-1)
ans[len-1]=0;
//i--;
}
}
printf("%s\n",ans);
}
return 0;
}
在挂机之前看了 B 题
HDU6288 缺失的数据范围
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 3593 Accepted Submission(s): 721
Problem Description
著名出题人小Q出过非常多的题目,在这个漫长的过程中他发现,确定题目的数据范围是非常痛苦的一件事。
每当思考完一道题目的时间效率,小Q就需要结合时限以及评测机配置来设置合理的数据范围。
因为确定数据范围是一件痛苦的事,小Q出了非常多的题目之后,都没有它们设置数据范围。对于一道题目,小Q会告诉你他的算法的时间复杂度为O(nalogbn),且蕴含在这个大O记号下的常数为1。同时,小Q还会告诉你评测机在规定时限内可以执行k条指令。小Q认为只要na(⌈log2n⌉)b不超过k,那么就是合理的数据范围。其中,⌈x⌉表示最小的不小于x的正整数,即x上取整。
自然,小Q希望题目的数据范围n越大越好,他希望你写一个程序帮助他设置最大的数据范围。
Input
第一行包含一个正整数T(1≤T≤1000),表示测试数据的组数。
每组数据包含一行三个正整数a,b,k(1≤a,b≤10,106≤k≤1018),分别描述时间复杂度以及允许的指令数。
Output
对于每组数据,输出一行一个正整数n,即最大可能的n。
Sample Input
3
1 1 100000000
2 1 100000000
1 3 200000000
Sample Output
4347826
2886
48828
思路:
给出a ,b ,k
根据公式求得 最大的 n 使得 n ^ a * (log2 (n)) ^ b <= k
感觉二分就可以
但是 没注意到 math 头文件中的log函数 不能用于long long
所以要手写 log2(n)
同时还有一个注意点是
当乘的过程中 已经超出k 的大小 就直接找下一个mid
所以在看了题解之后 自己写了一遍代码
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
#define LL long long
LL aa[62];
LL t, a, b;
LL k;
LL Log(LL x)
{
LL pos = lower_bound(aa+1, aa + 61, x) - aa;
return pos;
}
bool pp(LL x)
{
LL sum = 1, sum2 = 1;
for (LL i = 0; i < a; i++) {
if (sum > k / x) {
return false;
}
sum *= x;
if (sum > k) {
return false;
}
}
LL h = Log(x);
for (LL i = 0; i < b; i++) {
if (sum2 > k / h) {
return false;
}
sum2 *= h;
if (sum2 > k) {
return false;
}
}
if (sum > k / sum2) {
return false;
}
if (sum * sum2 <= k) {
return true;
}
}
int main()
{
aa[0] = 1;
for (int i = 1; i < 60; i++) {
aa[i] = aa[i - 1] * 2;
}
scanf("%lld", &t);
for (int i = 0; i < t; i++) {
scanf("%lld%lld%lld", &a, &b, &k);
LL l = 1, r = k, mid, ans = 0;
while (l <= r) {
mid = (l + r) / 2;
if (pp(mid)) {
l = mid + 1;
ans = mid;
} else {
r = mid - 1;
}
}
// cout << a << " " << mid << endl;
printf("%lld\n", ans);
}
return 0;
}
还有A题感觉可以做
最开始想的是线段树
后来发现查询的时候 可能会出错
所以稍微看了一下 莫队算法 结果另一道 E题是树上莫队……
待填坑。。。
HDU6290 奢侈的旅行
Time Limit: 14000/7000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 2066 Accepted Submission(s): 427
Problem Description
高玩小Q不仅喜欢玩寻宝游戏,还喜欢一款升级养成类游戏。在这个游戏的世界地图中一共有n个城镇,编号依次为1到n。
这些城镇之间有m条单向道路,第i 条单项道路包含四个参数ui,vi,ai,bi,表示一条从ui号城镇出发,在vi号城镇结束的单向道路,因为是单向道路,这不意味着小Q可以从vi沿着该道路走到ui。小Q的初始等级level为1,每当试图经过一条道路时,需要支付cost=log2level+ailevel点积分,并且经过该道路后,小Q的等级会提升ai级,到达level+ai级。但是每条道路都会在一定意义上歧视低消费玩家,准确地说,如果该次所需积分cost<bi,那么小Q不能经过该次道路,也不能提升相应的等级。
注意:本游戏中等级为正整数,但是积分可以是任意实数。
小Q位于1号城镇,等级为1,现在为了做任务要到n号城镇去。这将会是一次奢侈的旅行,请写一个程序帮助小Q找到需要支付的总积分最少的一条路线,或判断这是不可能的。
Input
第一行包含一个正整数T(1≤T≤30),表示测试数据的组数。
每组数据第一行包含两个整数n,m(2≤n≤100000,1≤m≤200000),表示城镇数和道路数。
接下来m行,每行四个整数ui,vi,ai,bi(1≤ui,vi≤n,ui≠vi,0≤ai≤109,0≤bi≤60),分别表示每条单向道路。
Output
对于每组数据,输出一行一个整数,即最少所需的总积分的整数部分,如:4.9999输出4,1.0输出1。若不存在合法路线请输出−1。
Sample Input
1
3 3
1 2 3
2 2 3
1 6 1
3 5 0
Sample Output
2
这个题目是看了 其他人的题解写的……
因为时间有限制
所以要用堆优化的迪杰斯特拉算法
加了一些自己对代码的理解
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
#define LL long long
const int maxn = 200005;
struct edge {
int u, v, a, b, next;
} e[maxn];
int num, head[maxn];
void insert_edge(int u, int v, int a, int b)
{
e[num].a = a;
e[num].b = b;
e[num].u = u;
e[num].v = v;
e[num].next = head[u];
head[u] = num++;
}
struct node {
int id;
LL d;
node (int id,LL d):id(id),d(d){}
bool operator < (const node &A)const {
return d>A.d;
}
//重载<
//优先队列反的
};
LL d[maxn];
bool vis[maxn];
int dis(int s, int t)
{
memset(d, 0x3f, sizeof d);//将d数组的所有值变成最大
memset(vis, 0, sizeof vis);
priority_queue<node> q;//优先队列 堆
q.push(node(s,1));
d[s] = 1;
while (!q.empty()) {
node tp1 = q.top();//根节点
q.pop();
int tp = tp1.id;
if (tp == t) {
for (int i = 1;; i++)
if ((1LL << i) > tp1.d) {
return i - 1;
}
//找到第一个比根节点短的路
}
if (vis[tp]) {
continue;
}
vis[tp] = 1;//标记经过的点
for (int i = head[tp]; i != -1; i = e[i].next) {
if (vis[e[i].v]) {
continue;
}
//已经经过了这个点
if (((e[i].a + tp1.d) / tp1.d) >= (1LL << e[i].b) && e[i].a + tp1.d < d[e[i].v]) {
d[e[i].v] = e[i].a + tp1.d;
q.push(node(e[i].v, d[e[i].v]));
}
//判断能否通过这条边
//可以通过的话就将这条边加入到优先队列中
}
}
return -1;
}
int main ()
{
int T;
scanf("%d", &T);
while (T--) {
memset(head, -1, sizeof head);
num = 0;
int u, v, a, b;
int N, M;
scanf("%d%d", &N, &M);
for (int i = 0; i < M; i++) {
scanf("%d%d%d%d", &u, &v, &a, &b);
insert_edge(u, v, a, b);
}
printf("%d\n", dis(1, N));
}
return 0;
}
374



被折叠的 条评论
为什么被折叠?



