第一次写解题报告,水平有限,欢迎补充!
这次的题目稍微排个难度顺序吧(仅个人观点)
Problem D The Heros 字符串查找
Problem F 三国杀 模拟题
Problem G 懒惰的妹纸 简单的数学题
Problem E Ants Run! 数学题
Problem H Fruit Ninja 数学题
Problem C UESTC冠军杯 模拟题
Problem DThe Heros
简单的字符串查找问题,由于数据范围很小,可以写一个裸的查找,也可以敲KMP,或者什么都不想写的话可以直接用strstr()乱搞过去了
至于strstr()函数的具体实现,不知道是否为KMP算法
Problem F三国杀
乍一看有人以为是线段树,其实就是很简单的模拟题
对于"N1 S Num"操作,用一个equip[i]的数组来维护,每次更新equip[i].dmg(攻击)和euip[i].def(防守)
对于"K A B"操作,先计算dis(A , B) = min(B - A , B + N - A) (当A < B时)
Dis(A,B) = dis(A , B) - equip[A].dmg + equip[B].def ,检查其是否小于等于1即可。
有一点字符串处理,小心一点就是。
Problem G懒惰的妹纸
很基础的数学题,讨论几种情况就行了
<1>t1 < a
<2>a <= t1 <= b , t1 - t < a
t1 - t >= a
<3>t1-t > b
<4>t1 - t <= b
ProblemEAnts Run!
需要动一下脑子的数学题
题目的要求是任何一只蚂蚁追赶到他前一只蚂蚁就会终止(第一只蚂蚁则追到最后一只)
首先,当所有蚂蚁速度都相同的时候,他们会永远地转圈圈。
否则,我们考虑这样一队蚂蚁,他们的速度为4 3 2 1
我们做出他们和前一只蚂蚁的速度差,得到3 -1 -1 -1
如果这样一队蚂蚁在圆上,只有可能第一只蚂蚁能追到最后一只蚂蚁
也就是说,我们可以将这一队蚂蚁一开始放在圆上的一个点(两两之间距离无穷小),那么这队蚂蚁走完这个圆就是第一只蚂蚁和最后一只蚂蚁的速度差的这个值(我们称之为“相对速度”)跑完全程
再考虑这样的蚂蚁队列,速度为3 2 1 4 3 2 1
我们实际上可以看作是两队蚂蚁3 2 1 | 4 3 2 1
同样可以照上述方式处理得到和前一只蚂蚁的相对速度:2 -1 -1 3 -1 -1 -1
这样两队蚂蚁,我们当然可以将每一队放在圆的一个点上,这个时候,队1的蚂蚁头要追队2的尾,队2的头要追队1的尾,由于我们得到的是相对速度,可以将每一队的蚂蚁尾看作在圆上不动。
为了使游戏时间尽可能长,我们当然希望的是两队蚂蚁头同时到达另一队的尾,所以即两个头的相对速度跑完全程
同理,我们可以推广到N队蚂蚁的情况。
ProblemHFruit Ninja
这个题很蛋疼,一开始看到数据在long long的范围内,觉得很难搞。
但是读题发现,(1 <= M , N <= 50) ,感觉貌似很水的一道题,是不是那个long long的范围在吓我们,于是乱搞一通,一交,WA了。。。
之后很久都不知道很大的答案是如何得到的。
想多了就知道55……5这样坑爹的情况貌似是可以构造出很大的答案的。
现在讨论如下的情况:
当m % 10 == 0 时,一定可以得到INF(只用选择一个10的倍数往上加就行了)
否则,当m%5 == 0时,
<1>若n % 5 == 0,则一定可以得到INF
<2>若n % 5 != 0,则可能出现55……5的情况。
这个时候,我们需要计算一下,由于1<=M<=50,则这是可取的M的值为5,15,25,35,45.
55……5 = 5 * a + k * M (5 * a为初始分数,k为正整数)
等式两边同时除以 5,即
11……1 = a + k * (M / 5)
当M = 5时,11……1 = a + k,则55555LL这个数为最大的一次各位数相等
当M = 15时,11……1 = a + k * 3,11……1 mod 3(“1”的个数从5个开始)得到的值为2,0,1,2,0,1……
故此时取“1”,得到的值尽可能大,即M=5时,5555555LL(7个“5”)会出现最大的一次各位数相等
当M = 25时,11……1 = a + k * 5,11……1 mod 5 得到的值是1,1,……故此时取“非1的值”,就不会得到各位数相等的数,故答案是INF
当M = 35时,11……1 = a + k * 7,11……1 mod 7 得到的值是2 ,0,1,4,6,5,2,0,1,4,……故此时取“3”,就不会得到各位数相等的数,故答案是INF
当M = 45时,11……1 = a + k * 9,11……1 mod 9 得到的值是5,6,7,8,0,1,2,3,4,5,……故此时去“4”,得到的值尽可能大,即M=45时,5555555555555LL(13个“5”)会出现最大的一次各位数相等
否则,最大情况就是max(9999 + n + ((9999 + n) % 5 : n : 0), 10000 + m)
Problem C UESTC冠军杯
我只想说,这个是一个很恶心的模拟题,没有任何思考难度,仅仅是恶心,看到比赛时仅一人通过就知道了。。。
这道题周日晚上我上晚自习开始敲,敲得比较慢,由于之前做恶心模拟题留下阴影了,所以很谨慎,每敲一部分就开始测试一下数据,敲了整整2个小时码完了这道题。
总之,没做过同一类题目的同学还是要做一下这道题来练练手。
之后附上自己的代码吧:
Problem D
/*
* ID: Allen_3
* Prob: The Heros
* LANG: C++
*/
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
char str[52];
}; //node
node temp[12];
int main()
{
int n , m;
scanf("%d" , &n);
for (int i = 0;i < n;i ++)
scanf("%s" , temp[i].str);
scanf("%d" , &m);
for (int i = 0;i < m;i ++)
{
bool flag = false;
char str[52];
scanf("%s" , str);
for (int i = 0;i < n;i ++)
if (strstr(str , temp[i].str) != NULL)
{
printf("A new hero discovered\n");
flag = true;
break;
}
if (!flag)
printf("Just an ordinary person\n");
} //
return 0;
} //main
Problem F
/*
* ID: Allen_3
* Prob: Three Kingdoms
* LANG: C++
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
#define output "test.txt"
struct node
{
int dmg , def;
}; //node
int T , n , m;
node equip[1002];
inline int min(int a , int b)
{
if (a < b)
return a;
return b;
} //min
int main()
{
//freopen(output , "w" , stdout);
scanf("%d" , &T);
for (int i = 0;i < T;i ++)
{
printf("Case #%d:\n" , i + 1);
memset(equip , 0 , sizeof(equip));
char ch;
scanf("%d%d" , &n , &m);
scanf("%c" , &ch); //\n
for (int i = 0;i < m;i ++)
{
scanf("%c" , &ch);
if (ch == 'K')
{
int u , v , dis;
scanf("%d%d" , &u , &v);
if (u < v)
dis = min(v - u , u + n - v);
else
dis = min(u - v , v + n - u);
if (dis - equip[u].dmg + equip[v].def <= 1)
printf("Yes!\n");
else
printf("I'm sorry.\n");
}
else
{
int u = 0 , num;
while (ch != ' ')
{
u = u * 10 + (ch - '0');
scanf("%c" , &ch);
} //
scanf("%c" , &ch); // + or -
scanf("%d" , &num);
if (ch == '+')
{
equip[u].def = num;
}
else
{
equip[u].dmg = num;
}
}
scanf("%c" , &ch); //\n
} //
printf("\n");
} // for T
return 0;
} //main
Problem G
/*
* ID: Allen_3
* Prob: Lazy Girl
* LANG: C++
*/
#include<cstdio>
using namespace std;
int main()
{
int T;
scanf("%d" , &T);
for (int i = 0;i < T;i ++)
{
int a , b , t , t1;
scanf("%d%d%d%d" , &a , &b , &t , &t1);
if (t1 <= a)
printf("0.0000\n");
else if (t1 - t >= a)
{
if (t1 <= b)
printf("%.4f\n" , (double)t / (double)(b - a));
else
{
if (t1 - t >= b)
printf("0.0000\n");
else
printf("%.4f\n" , (double)(b + t - t1) / (double)(b - a));
}
}
else
{
if (t1 <= b)
printf("%.4f\n" , (double)(t1 - a) / (double)(b - a));
else
printf("1.0000\n");
}
} //for i
return 0;
} //main
Problem E
/*
* ID: Allen_3
* Prob: Ants Run!
* LANG: C++
*/
#include<cstdio>
using namespace std;
#define pi 3.1415926
#define INF 3f3f3f3f
int T , n , r;
int a[10002];
int main()
{
scanf("%d" , &T);
for (int i = 0;i < T;i ++)
{
bool flag = false;
scanf("%d%d" , &n , &r);
for (int i = 0;i < n;i ++)
{
scanf("%d" , &a[i]);
if (i && a[i] != a[i - 1])
flag = true;
}
if (!flag)
{
printf("Inf\n"); continue;
}
a[n] = a[0];
int sum = 0;
for (int i = 0;i < n;i ++)
{
a[i] = a[i + 1] - a[i];
if (a[i] > 0)
sum += a[i];
}
printf("%.3f\n" , 2 * pi * (double)r / (double)sum);
} //for i _ T
return 0;
} //main
Problem H
代码和题解有一定出入,题解是之后想出来的数学办法,对于M=5,M=15,M=45的情况是枚举出来的答案
/*
* ID: Allen_3
* Prob: Fruit Ninja
* LANG: C++
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
#define input "test.txt"
#define output "result.txt"
#ifdef unix
#define LL_FMT "%lld"
#else
#define LL_FMT "%I64d"
#endif
int a[2002];
int T , cnt = 0;
long long ans , n , m;
inline long long max(long long x , long long y)
{
if (x > y)
return x;
return y;
} //max
long long solve(int x)
{
long long num = 5555LL;
for (int i = 1;i <= 100;i ++)
{
num = num * 10LL + 5LL;
if (!((num - x) % m))
return (num + m + n);
} //for i
} //solve
int main()
{
//freopen(input , "r" , stdin);
//freopen(output , "w" , stdout);
for (int i = 1;i <= 10000;i ++)
if (!(i % 5))
a[cnt ++] = i;
scanf("%d" , &T);
for (int i = 0;i < T;i ++)
{
printf("Case #%d: " , i + 1);
scanf(LL_FMT LL_FMT , &m , &n);
//printf(LL_FMT" "LL_FMT" ", m , n);
if (!(m % 10LL))
{
printf("INF\n");
}
else if (!(m % 5LL) && (m % 10LL))
{
if (!(n % 5LL))
{
printf("INF\n");
}
else
{
if (m == 35 || m == 25)
{
printf("INF\n"); continue;
}
ans = 0;
for (int i = 0;i < cnt;i ++)
ans = max(ans , solve(a[i]));
printf(LL_FMT"\n" , ans);
}
}
else
{
ans = 9999LL + n;
if (!(ans % 5LL))
ans += m;
if (10000LL + m > ans)
ans = 10000LL + m;
printf(LL_FMT"\n" , ans);
}
} //for i _ T
return 0;
} //main
Problem C
代码略丑,请见谅。。。
/*
* ID: Allen_3
* Prob: UESTC Champion Cup
* LANG: C++
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define output "result.txt"
struct _info
{
char name[20];
int points , goal , lose , delta , Rank;
}; //_info
int T , n , m;
_info List[30];
inline int max(int a , int b)
{
if (a > b)
return a;
return b;
} //max
int get_ID(char *str)
{
for (int i = 0;i < n;i ++)
if (strcmp(str , List[i].name) == 0)
return i;
} //get_ID
int get_len(int num)
{
if (num == 0) return 1;
int ans = 0;
if (num < 0)
ans ++;
while (num)
{
ans ++;
num = num / 10;
} //
return ans;
} //get_len
bool cmp_points(_info a , _info b)
{
return (a.points > b.points);
} //cmp_points
bool cmp_delta(_info a , _info b)
{
return (a.delta > b.delta);
} //cmp_delta
bool cmp_goal(_info a , _info b)
{
return (a.goal > b.goal);
} //cmp_goal
bool cmp_name(_info a , _info b)
{
if (strcmp(a.name , b.name) < 0)
return true;
return false;
} //cmp_name
void print()
{
int max_Rank = 4 , max_name = 6 , max_points = 3 , max_goal = 1 , max_lose = 1 , max_delta = 1;
for (int i = 0;i < n;i ++)
{
int len;
max_name = max(max_name , strlen(List[i].name));
max_points = max(max_points , get_len(List[i].points));
max_goal = max(max_goal , get_len(List[i].goal));
max_lose = max(max_lose , get_len(List[i].lose));
max_delta = max(max_delta , get_len(List[i].delta));
}
int sum;
sum = max_Rank + max_name + max_points + max_goal + max_lose + max_delta + 12 + 5;
printf("+");
for (int i = 0;i < sum;i ++) printf("-");
printf("+\n");
// Row 1
printf("| Rank |");
for (int i = 0;i < (max_name - 4) / 2;i ++) printf(" ");
printf("Player");
for (int i = 0;i < (max_name - 3) / 2;i ++) printf(" ");
printf("|");
for (int i = 0;i < (max_points - 1) / 2;i ++) printf(" ");
printf("Pts");
for (int i = 0;i < (max_points ) / 2;i ++) printf(" ");
printf("|");
for (int i = 0;i < (max_goal + 1) / 2;i ++) printf(" ");
printf("G");
for (int i = 0;i < (max_goal + 2) / 2;i ++) printf(" ");
printf("|");
for (int i = 0;i < (max_lose + 1) / 2;i ++) printf(" ");
printf("L");
for (int i = 0;i < (max_lose + 2) / 2;i ++) printf(" ");
printf("|");
for (int i = 0;i < (max_delta + 1) / 2;i ++) printf(" ");
printf("D");
for (int i = 0;i < (max_delta + 2) / 2;i ++) printf(" ");
printf("|\n");
// Row 2
for (int i = 0;i < n;i ++)
{
printf("|");
for (int j = 0;j < max_Rank + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_name + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_points + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_goal + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_lose + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_delta + 2;j ++) printf("-");
printf("|\n");
printf("|");
for (int j = 0;j < (4 + 2 - get_len(List[i].Rank)) / 2;j ++) printf(" ");
printf("%d" , List[i].Rank);
for (int j = 0;j < (4 + 3 - get_len(List[i].Rank)) / 2;j ++) printf(" ");
printf("|");
for (int j = 0;j < (max_name + 2 - strlen(List[i].name)) / 2;j ++) printf(" ");
printf("%s" , List[i].name);
for (int j = 0;j < (max_name + 3 - strlen(List[i].name)) / 2;j ++) printf(" ");
printf("|");
for (int j = 0;j < (max_points + 2 - get_len(List[i].points)) / 2;j ++) printf(" ");
printf("%d" , List[i].points);
for (int j = 0;j < (max_points + 3 - get_len(List[i].points)) / 2;j ++) printf(" ");
printf("|");
for (int j = 0;j < (max_goal + 2 - get_len(List[i].goal)) / 2;j ++) printf(" ");
printf("%d" , List[i].goal);
for (int j = 0;j < (max_goal + 3 - get_len(List[i].goal)) / 2;j ++) printf(" ");
printf("|");
for (int j = 0;j < (max_lose + 2 - get_len(List[i].lose)) / 2;j ++) printf(" ");
printf("%d" , List[i].lose);
for (int j = 0;j < (max_lose + 3 - get_len(List[i].lose)) / 2;j ++) printf(" ");
printf("|");
for (int j = 0;j < (max_delta + 2 - get_len(List[i].delta)) / 2;j ++) printf(" ");
printf("%d" , List[i].delta);
for (int j = 0;j < (max_delta + 3 - get_len(List[i].delta)) / 2;j ++) printf(" ");
printf("|\n");
} // The Players Info
printf("|");
for (int j = 0;j < max_Rank + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_name + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_points + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_goal + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_lose + 2;j ++) printf("-");
printf("|");
for (int j = 0;j < max_delta + 2;j ++) printf("-");
printf("|\n");
printf("\n");
} //print
int main()
{
//freopen(output , "w" , stdout);
char ch;
scanf("%d" , &T);
for (int i = 0;i < T;i ++)
{
memset(List , 0 , sizeof(List));
scanf("%d%d" , &n , &m);
scanf("%c" , &ch); // read '\n'
for (int i = 0;i < n;i ++)
{
scanf("%s" , List[i].name);
scanf("%c" , &ch); // read '\n'
} //for i _ n
for (int i = 0;i < m;i ++)
{
char name_1[20] , name_2[20];
int goal_1 , goal_2;
scanf("%s" , name_1); scanf("%c" , &ch);
scanf("%d" , &goal_1);
scanf("%c%c%c" , &ch , &ch , &ch);
scanf("%d" , &goal_2);
scanf("%s" , name_2);
//deal the data
int u = get_ID(name_1);
int v = get_ID(name_2);
List[u].goal += goal_1; List[u].lose += goal_2;
List[v].goal += goal_2; List[v].lose += goal_1;
if (goal_1 > goal_2)
List[u].points += 3;
else if (goal_1 < goal_2)
List[v].points += 3;
else
{
List[u].points ++; List[v].points ++;
}
} //for i _ m
for (int i = 0;i < n;i ++)
List[i].delta = List[i].goal - List[i].lose;
sort(List , List + n , cmp_points);
int j;
for (int i = 0;i < n - 1;i += j - i)
{
for (j = i + 1;j <= n && List[j].points == List[i].points;j ++) {}
if (j > n)
j = n;
sort(List + i , List + j , cmp_delta);
} //for i _ j delta
for (int i = 0;i < n - 1;i += j - i)
{
for (j = i + 1;j <= n && List[j].points == List[i].points
&& List[j].delta == List[i].delta ;j ++) {}
if (j > n)
j = n;
sort(List + i , List + j , cmp_goal);
} //for i _ j goal
//detemine the ranks
List[0].Rank = 1;
for (int i = 1;i < n;i ++)
if (List[i].points == List[i - 1].points
&& List[i].delta == List[i - 1].delta
&& List[i].goal == List[i - 1].goal)
List[i].Rank = List[i - 1].Rank;
else
List[i].Rank = i + 1;
for (int i = 0;i < n - 1;i += j - i)
{
for (j = i + 1;j <= n && List[j].points == List[i].points
&& List[j].delta == List[i].delta
&& List[j].goal == List[i].goal ;j ++) {}
if (j > n)
j = n;
sort(List + i , List + j , cmp_name);
} //for i _ j name
print();
} //for i _ T
//fclose(stdout);
return 0;
} //main
至于Problem B。。。水平有限,还没想出来,之后补充。。。Orz 做出来的人。