SUST ACM Summer Training(陕西科技大学 暑期ACM训练)
10道结构体和排序类型问题
题解
HDU 1029 Ignatius and the Princess IV
题目描述
求给出测试序列中,出现次数至少为(n+1)/2的数字
思路
把序列排序一遍出现次数为(n+1)/2次的数字必定在数据列的中间
#include
#include
#include
#define Len 1000100
using namespace std;
int n,a[Len];
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a));
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
printf("%d\n",a[(n+1)/2]);
}
return 0;
}
HDU 1040 As Easy As A+B
题目描述
给出测试序列,按升序输出序列
思路
直接sort()即可
#include
#include
using namespace std;
int t,n,a[1010];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
printf("%d",a[0]);
for(int i = 1; i < n ; i++)
printf(" %d",a[i]);
printf("\n");
}
return 0;
}
HDU 1106 排序
题目描述
给出一个数字字符串,以5为分割,把每个数排序后输出,注意00表示0,01表示1
思路
为了避免00这种情况,从后往前判断,遇到5跳过否则依次转换成整形数存进数组,最后排序输出。
#include
#include
#include
#include
using namespace std;
char s[1010];
int l,x,i,j,a[1010];
int main()
{
while(scanf("%s",s)!=EOF)
{
memset(a,0,sizeof(a));
l = strlen(s);
x = 0;
for(i = l-1, j = 0; i >= 0; i--)
{
if(s[i] == '5')
continue;
else
{
while(s[i] != '5')
{
if(i == -1)
break;
a[j] += pow(10,x++) * (s[i--] - '0');
}
j++;
x = 0;
}
}
sort(a,a+j);
printf("%d",a[0]);
for(i = 1; i < j; i++)
printf(" %d",a[i]);
printf("\n");
}
return 0;
}
HDU 1209 Clock
题目描述
给出5个时刻,让你计算每个时刻的时针与分针的夹角,然后按夹角从小到大排序,如果角度相同,则按时间先后顺序排序,最后输出中间的时刻
思路
简单的换算题,时针每小时转30°,每分钟转0.5°,分针每分钟转6°,所以可以推导出换算公式。最后两个针的角度相减算出绝对值角度,如果大于180°的话,再用360°减去。
#include
#include
#include
using namespace std;
struct tt
{
double angle;
int h;
int m;
}t[6];
int T,n;
bool cmp(tt x,tt y)
{
if(x.angle == y.angle)
return x.h < y.h;
return x.angle < y.angle;
}
int main()
{
scanf("%d",&T);
while(T--)
{
for(int i = 0; i < 5; i++)
{
scanf("%d:%d",&t[i].h,&t[i].m);
t[i].angle = (t[i].h > 12) ? abs( (t[i].h - 12) * 30 + 0.5 * t[i].m - t[i].m * 6) : abs( t[i].h * 30 + 0.5 * t[i].m - t[i].m * 6);
t[i].angle = (t[i].angle > 180) ? 360 - t[i].angle : t[i].angle;
}
sort(t,t+5,cmp);
printf("%02d:%02d\n",t[2].h,t[2].m);
}
return 0;
}
HDU 1236 排名
题目描述
先给出每道题的总分,依次给出每个学生的学号、通过的题目数量、每道题的得分。
让你根据成绩进行排序,如果成绩一样,则按照学号进行排序
思路
结构体保存学生的信息,然后排序,特别注意一点就是学号要按照字典序排序
#include
#include
#include
using namespace std;
struct stu
{
char name[22];
int num;
int score;
}s[1100];
int n,m,g,x,c,score[11];
bool cmp(stu x,stu y)
{
if(x.score == y.score)
return strcmp(x.name,y.name) > 0 ? 0 : 1;
return x.score > y.score;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n == 0)
break;
scanf("%d%d",&m,&g);
c = 0;
memset(s,0,sizeof(s));
for(int i = 1; i <= m; i++)
scanf("%d",&score[i]);
for(int i = 1; i <= n; i++)
{
scanf("%s %d",s[i].name,&s[i].num);
for(int j = 1; j <= s[i].num; j++)
{
scanf("%d",&x);
s[i].score += score[x];
}
if(s[i].score >= g)
c++;
}
sort(s+1,s+n+1,cmp);
printf("%d\n",c);
for(int i = 1; i <= n; i++)
if(s[i].score >= g)
printf("%s %d\n",s[i].name,s[i].score);
else
break;
}
return 0;
}
HDU 1280 前m大的数
题目描述
给出序列,把它们两两相加到前N*(N-1)/2,然后降序输出前N项
思路
暴力求解,用新数组保存两两相加的值,然后降序排序,遍历输出前N项
#include
#include
using namespace std;
int n,m,i,j,k,a[3010],b[5000100];
bool cmp(int x,int y)
{
return x > y;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i = 0; i < n; i++)
scanf("%d",&a[i]);
for(i = 0,k = 0; i < n; i++)
{
for(j = i + 1; j < n; j++)
b[k++] = a[i] + a[j];
}
sort(b,b+k,cmp);
printf("%d",b[0]);
for(int i = 1; i < m; i++)
printf(" %d",b[i]);
printf("\n");
}
return 0;
}
HDU 1379 DNA Sorting
题目描述
给出字符串,按照逆字典序算出每个字符的逆字典序的个数的和,然后按照每个序列逆字典序个数总和进行排序输出
思路
用结构体保存字符串和逆字典序个数和,最后排序输出
#include
#include
#include
using namespace std;
struct DNA
{
char s[55];
int num;
}str[110];
int T,l,n;
bool cmp(DNA x,DNA y)
{
return x.num < y.num;
}
int main()
{
scanf("%d",&T);
getchar();
while(T--)
{
scanf("%d%d",&l,&n);
getchar();
for(int i = 0; i < n; i++)
{
scanf("%s",str[i].s);
str[i].num = 0;
for(int j = 0; j < l; j++)
for(int k = j + 1; k < l; k++)
if(str[i].s[j] > str[i].s[k])
str[i].num++;
}
sort(str,str+n,cmp);
for(int i = 0; i < n; i++)
printf("%s\n",str[i].s);
if(T)
printf("\n");
}
return 0;
}
HDU 1391 Number Steps
题目描述
让你根据图的规律计算给出的坐标是否存在
思路
找规律,打表保存每一个存在的点,根据输入直接输出结果
#include
#include
using namespace std;
int t,x,y,map[5010][5010]={0};
int main()
{
for(int i = 0; i <= 5000; i++)
if(i % 2 == 0)
map[i][i] = i + i;
else
map[i][i] = i + i - 1;
for(int i = 2, j = 0; i <= 5000; i++)
{
if(i % 2 == 0)
map[i][j] = i + j;
else
map[i][j] = i + j - 1;
j++;
}
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&x,&y);
if(map[x][y])
printf("%d\n",map[x][y]);
else
printf("No Number\n");
}
return 0;
}
HDU 2673 shǎ崽 OrOrOrOrz
题目描述
给出序列,按照最大最小第二大,第二小的顺序把序列输出
思路
排序,逆序输出时候按照下标变化输出相应结果
#include
#include
using namespace std;
int n,a[10010];
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
//printf("%d",a[n-1]);
for(int i = n - 1; i >= n/2; i--)
{
if(i == n - 1)
printf("%d",a[i]);
else
printf(" %d",a[i]);
if(i == n/2 && n%2)
break;
printf(" %d",a[n - i - 1]);
}
printf("\n");
}
return 0;
}