目录
题目
冰墩墩和冰壶 | ||
Acceteped : 234 | Submit : 769 | |
Time Limit : 1000 MS | Memory Limit : 65536 KB | |
题目描述冰壶是被誉为“冰面上的国际象棋”,其计分规则是各自投壶,最后在大本营内,你有几个壶离圆心比对方所有壶离圆心都近就得到几分。 比如红方有两个壶,分别在坐标(1,1),(−2,1);黄方也有两个壶,分别在(1,0),(0,2)。 由于黄方的第一个壶离圆心更近,而黄方的第二个壶没有红方第一个壶近,所以最后黄方得1分,红方不得分。 现在冰墩墩每次都选择红方,它想知道它到底得了多少分? 输入格式第一行是一个整数T(1≤T≤3000),表示样例的个数。 每个样例的第一行是一个整数n(1≤n≤16),表示冰壶的数量。 以后每行一个冰壶的信息,为三个部分,第一个是一个字符,表示冰壶的颜色(R表示红色,Y表示黄色),后面是两个整数(数值的绝对值不超过1000),表示冰壶的坐标。 输入数据保证不会出现两个壶在同一个坐标。 输出格式依次输出每个样例的结果。结果为一行,分为两个部分,如果没有让对方得分,输出“Win”和分数,否则输出”Lose”和对方得分的分数,两者之间相隔一个空格。 样例输入2 4 Y 1 1 R -2 1 R 1 0 Y 0 2 4 Y 1 1 R 0 1 R 1 0 Y 0 2 样例输出Win 1 Win 2 |
思路分析
区分 " Win " & " Lose "
对两个队伍的d ( 距离圆心最近的距离 ) 进行比较
计算分值
对于胜队 , 取其各冰壶距离与败队d进行比较
此处容易犯错的是 , 误以为两队冰壶数量相等 , 为冰壶总数的一半
代码设计
需要实现的功能
正确获取并储存输入数据
计算各队圆心距
得到各队最小圆心距
判断优胜队
计算优胜队最终得分
需要的变量
仅针对输入以及思路分析而言 , 其余间接应用变量在各模块中自行添加
样例数 T
冰壶总数 n
冰壶坐标 x , y
各队冰壶数目cnty , cntr
各队冰壶圆心距 Y[20] , R[20]
各队冰壶最小圆心距 miny , minr
优胜队分数score
代码模块化处理
需初始化数据
int T;
//int n;main()中可有可无,作为局部变量也可
//以下变量在样例循环内初始化
int Y[20] = {0};
int R[20] = {0};
int cnty = 0;
int cntr = 0;
int miny = 3000000;
int minr = 3000000;
//int score = 0;此处将判断函数与输出函数合并,故作为局部变量,直接计算并输出
功能函数
//功能函数(没有应用其他函数的那种)一般建议写在所有函数前
int Distance(int a, int b){
return a * a + b * b;
}//计算圆心距,为方便比较不予开根号处理
输入函数
获取输入数据的同时获得最小圆心距
void Printin(int *Y, int *R, int *cnty, int *cntr, int *miny, int *minr){
int n;//由于n仅在存储数据时有用,因此此处作为局部变量出现
scanf("%d", &n);
getchar();//吸收多余的回车
while(n--){
char team;
int x, y;
scanf("%c %d %d", &team, &x, &y);
getchar();//吸收多余的回车
if(team == 'Y'){
*(Y + *cnty) = Distance(x, y);
*miny = (*(Y + *cnty) < *miny) ? *(Y + *cnty) : *miny;//最小圆心距
(*cnty)++;
}
else if(team == 'R'){
*(R + *cntr) = Distance(x, y);
*minr = (*(R + *cntr) < *minr) ? *(R + *cntr) : *minr;//最小圆心距
(*cntr)++;
}
}
}
判断/计算/输出函数
在存储数据时可顺便记录数据数量及取最大or最小值
判断时也可以顺便输出了
void Judge(int *Y, int *R, int *cnty, int *cntr, int *miny, int *minr){
int score = 0;
if(*miny < *minr){//判断优胜队伍,若相等算胜利,即两者均不得分,按题意算R队获胜
printf("Lose ");
for(int i = 0;i < *cnty;i++){
if(*(Y + i) < *minr) score++;//计算优胜队分数
}
printf("%d\n", score);
}
else{
printf("Win ");
for(int i = 0;i < *cntr;i++){
if(*(R + i) < *miny) score++;//计算优胜队分数
}
printf("%d\n", score);
}
}
主函数
int main(){
int T;
scanf("%d", &T);
while(T--){
int Y[20] = {0};
int R[20] = {0};
int cnty = 0;
int cntr = 0;
int miny = 3000000;
int minr = 3000000;
Printin(Y, R, &cnty, &cntr, &miny, &minr);
Judge(Y, R, &cnty, &cntr, &miny, &minr);
}
return 0;
}
提交代码
Problem: 1475 | User: 202105501225 | |
Memory: 1184K | Time: 31MS | |
Language: G++ | Result: Accepted |
#include <stdio.h>
int Distance(int a, int b){
return a * a + b * b;
}
void Printin(int *Y, int *R, int *cnty, int *cntr, int *miny, int *minr){
int n;
scanf("%d", &n);
getchar();
while(n--){
char team;
int x, y;
scanf("%c %d %d", &team, &x, &y);
getchar();
if(team == 'Y'){
*(Y + *cnty) = Distance(x, y);
*miny = (*(Y + *cnty) < *miny) ? *(Y + *cnty) : *miny;
(*cnty)++;
}
else{
*(R + *cntr) = Distance(x, y);
*minr = (*(R + *cntr) < *minr) ? *(R + *cntr) : *minr;
(*cntr)++;
}
}
}
void Judge(int *Y, int *R, int *cnty, int *cntr, int *miny, int *minr){
int score = 0;
if(*miny < *minr){
printf("Lose ");
for(int i = 0;i < *cnty;i++){
if(*(Y + i) < *minr) score++;
}
printf("%d\n", score);
}
else{
printf("Win ");
for(int i = 0;i < *cntr;i++){
if(*(R + i) < *miny) score++;
}
printf("%d\n", score);
}
}
int main(){
int T;
scanf("%d", &T);
while(T--){
int Y[20] = {0};
int R[20] = {0};
int cnty = 0;
int cntr = 0;
int miny = 3000000;
int minr = 3000000;
Printin(Y, R, &cnty, &cntr, &miny, &minr);
Judge(Y, R, &cnty, &cntr, &miny, &minr);
}
return 0;
}
收获及总结
对于指针的使用
更深刻的理解了指针与数组的关系
此处涉及的指向数组的指针 , 即是数组名 ( 指向数组首地址 )
所以此时在声明指针变量时 , 为int *Y ( 不是int *Y[]或其他 )
在使用函数时传输的变量也直接就是数组名
关于输入字符的小Tips
可以试试 , 把输入函数中的getchar()都删掉后
输入到字符变量team中的字符有什么变化
最直观的感受就是 , 数据还没输入完就输出结果了
原因在于此时%c读取了上一个scanf()的回车
解决办法有以下几种 :
- 在%c的前一个scanf() ( 此函数中需要加的scanf()有两处 ) 后使用getchar()
- 在%c的前一个scanf()末尾加上空格or ' \n 'or ' \t ' ( 两处 )
- 在%c前面加上空格or ' \n 'or ' \t ' ( 在其他人题解上看见的 , 感觉是最方便的 )
还在消化scanf中空格的作用
找到了两篇感觉还可以的解释
可以结合起来看
【C语言】scanf语句吃掉回车或者空格问题详解_scanf吃掉回车符是什么意思_Z小旋的博客-CSDN博客
scanf函数%c前为什么加空格_对于scanf()而言,%c_hhhhhyyyyy8的博客-CSDN博客
优化前想法及优化点及WA点
< 对各队数组按距离远近重新排序依次比较 > 变为 < 选择最近距离用于比较 >
< 判断与输出分开 > 变为 < 判断与输出合并 >
WA是因为读题时理解错误 , 认为两队冰壶数一定相同