T1026-浪(张鹏)
A. 有序序列合并:

解析:

本题是将两个升序排列的数组合并为一个数组,那就可以再定义一个大数组来存放所有的数据,再进行升序排列即可,首先用一个for循环去将第一个数组存入大数组,再把第二个数组接在第一个数组数据后面(从第一个数组的最后一个元素开始存入),最后用排序将大数组进行升序排列。
代码:
#include <stdio.h>
#include <string.h>
#define N 1000
#define M 2000
int main()
{
	int n,m,k;
	scanf("%d %d",&n,&m);
	int a[N],b[N];
	int i,j,t;
	for(i=0;i<n;i++)
	scanf("%d",&a[i]);
	for(i=0;i<m;i++)
	scanf("%d",&b[i]);
	int s[M];
	for(i=0;i<n;i++)
	{
		s[i]=a[i];
	}
	for(i=n,j=0;i<n+m;i++,j++)
	{
		s[i]=b[j];
	}
	for(i=0;i<n+m-1;i++)
	for(j=0;j<n+m-i-1;j++)
	if(s[j]>s[j+1])
	{
		t=s[j+1];
		s[j+1]=s[j];
		s[j]=t;
	}
	for(i=0;i<n+m;i++)
	printf("%d ",s[i]);
	return 0;
}

BDragon

解析:

本题的实质为排序,但是不能包含前导0,就得用逐位乘法去乘,对于c语言来说,处理到文件尾的方式是:while(scanf("%d",&a[0])!=EOF),核心代码只需要简单的冒泡排序即可。

代码:

#include <stdio.h>
int main()
{
	int a[4];
	while(scanf("%d",&a[0])!=EOF)
    {
        int n=4;
        int i,j,t;
        for(i=1;i<n;i++)
		scanf("%d",&a[i]);
        for(i=0;i<3;i++)
        for(j=0;j<3-i;j++)
        if(a[j]<a[j+1])
        {
        	t=a[j+1];
        	a[j+1]=a[j];
        	a[j]=t;
		}
        int ans=a[0]*1000+a[1]*100+a[2]*10+a[3]*1;
        printf("%d\n",ans);
    }
    return 0;
 } 

C.花样方阵:

解析:

对于本题,因为两人之间的移动互不影响,所以只需要单独计算每个人所需要的时间,再将最长的时间输出即可,计算每个人单独所需时间的方式为,需要横着走的格数加需要竖着走的格数(此处需要用到abs取绝对值函数,包含于<math.h>文件下)。

代码:

#include <stdio.h>
#include <math.h>
int max(int x,int y)
{
	return (x>y?x:y);
}
int s[100];
int main()
{
    int i,t;
    int x,y,a,b;
   scanf("%d",&t);
    while(t--)
    {
        int n;
           scanf("%d",&n);
        int m=-1;
        for(i=1;i<=n;i++)
        {
           scanf("%d %d %d %d",&x,&y,&a,&b);
            s[i]=abs(a-x)+abs(b-y);
            m=max(m,s[i]);
        }
        printf("%d\n",m);
    }
    return 0;
}

D.不重复数字:

解析:

本题为常规类型删去数组中重复元素只保留一个数,但是本题要求的时间复杂度很低,不能用常规的双层循环去做,也不能定义一个新数组,这些都会导致时间复杂度超出要求,那就可以多定义一个变量r指向数组首元素,在一个循环里去完成检索并删除。

代码:

#include <stdio.h>
int m[50000];
int main()
{
    int T,i,j,r=0,x;
    int n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++)
        scanf("%d",&m[i]);
    		for(i=0;i<n;i++)
	 	{
			for(j=0;j<r;j++)
			if(m[j]==m[i]) break;
			if(j==r)
			m[r++]=m[i];
	 	}
	 		  for(i=0;i<r;i++)
		printf("%d ",m[i]);
		printf("\n");
		 r=0;
    }
    return 0;
}

E.H和迷宫

解析:

想要求最大能扣减的血量,只要保证最有效的药水先用即可,那就可以给药水进行排序,并且按照从大到小的顺序给怪兽使用即可。

代码:

#include <stdio.h>
int main()
{
    int n,i,j,t;
    int a[3];
    scanf("%d",&n);
        for(i = 0; i < 3; i ++) 
		scanf("%d",&a[i]);
        for(i=0;i<2;i++)
        for(j=0;j<2-i;j++)
        if(a[j]<a[j+1])
        {
        	t=a[j+1];
        	a[j+1]=a[j];
        	a[j]=t;
		}
        int ans=n;
       for(i=0;i<3;i++)
      ans*=1-a[i]/100.0;
        printf("%d\n",n-ans);
    return 0;
}

F.主持人的烦恼

解析:首先定义数组a[]存放每个同学的颜值,讲数组从小到大排序,然后相邻数作差与给定的m比较,因为一个人只能出现在一个组中,所以如果满足组队条件在给结果加一的同时需要给数组下标加一。

代码:

#include <stdio.h> 
#include <stdlib.h>
int comp(const void*a,const void*b)
{
    return *(int*)a-*(int*)b;
}
int main()
{
    int i,n,j,t,m;
    int a[100000];
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(i=0;i<n;i++)
         scanf("%d",&a[i]);
        qsort(a,n,sizeof(int),comp);
         int s=0;
        for(i=0;i<n-1;i++)
        {
             if(a[i+1]-a[i]<m)
             {
                 s++;
                 i++;
             }
        }
        printf("%d\n",s);
    }
}

G.粟酱的文明2

解析:

本题题意中提出要求,必须要给自己留有一块空的土地,分析题意,想要建立最多的外交关系,必须使自己国家的土地大于能建立起外交关系的国家数。我们可以讲每个国家拥有的土地数存入一个数组a[],对数组从大到小排序,因为必须要给自己留有一块空的土地,所以先给整个数组减一,在进行比较,当a[i]>i-1的时候就能最多建立起i个外交关系。

代码:

#include <stdio.h>
#include <stdlib.h>
 int cmp( const void *a, const void *b)
 {    
 return *(int*)b-*(int*)a;
 }
int main()
{
	int t,n;
	int i;
	int a[1000];int *p=&a[1];
    scanf("%d",&t);
    while(t--) 
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            a[i]-=1;
        }
        qsort(p,n,sizeof(int),cmp);
        int ans=0;
        for(i=1;i<=n;i++)
        {
            if(a[i]<i-1)break;
            ans=i;
        }
        if(ans==1)
		printf("0\n");
        else 
        printf("%d\n",ans);
    }
    return 0;
}

H.小龙的秘密:

解析:检查字符串是否相同,只要对字符串进行排序,在检测字符串是否相同即可。

代码:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
	string s1,s2;
	cin>>s1;
	cin>>s2;
	sort(s1.begin(),s1.end());
	sort(s2.begin(),s2.end());
	if(s1==s2)
	cout<<"^_^";
	else
	cout<<"-_-#";
}

I. Laptop

解析:

只有内存和速度两个性能都不如另一台电脑时才叫“”完虐,我们定义两个数组去分别存放速度和内存,定义一个结果初始化为0,用if判断条件是两个性能都不如另一台电脑时给结果+1.

代码:

#include<stdio.h>
int main()
{
 int n;
 scanf("%d",&n);
 int i,j,count=0;
 int M[n],S[n];
 for(i=0;i<n;i++)
 {
  scanf("%d %d",&M[i],&S[i]);
 }
 for(i=0;i<n;i++)
 {
  for(j=0;j<n;j++)
  {
   if(M[i]<M[j] && S[i]<S[j] && i!=j)
   {
    count++;
    break;
   }
  }
 }
 printf("%d",count);
 return 0;
 } 

J.Soccer Standings

解析:

本题的题意是输入每一组的球队名称,两两球队之间比赛的得分,然后计算出每一支球队的得分,胜利场数,平局场数,失败场数,进球数和被进球数,并且按照一定的排序方式输出这些数据,排序方式为:

1.      总得分从高到低;

2.      得分相同时进球数减去被进球数的差从高到低;

3.      前两者相同,总进球数从高到低;

4.      前三者相同,按队伍名的字母顺序排列;

因为每支球队需要计算的数据分类都一样,所以可以使用结构体来包含“得分,胜利场数,平局场数,失败场数,进球数和被进球数”;

因为每两支球队都有比赛,需要统计数据并且计算,所以可以定义一个函数专门用来计算数据,函数的功能实现在代码后已注释;

需要用特殊的排序方式对结构体进行排序,所以必须按照题目要求自定义比较方式在用sort函数进行排序;

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m;
struct node
{
	string name;
	int points,wins,losses,draws,scored,allowed;     //每支队伍的得分,胜场数,失败场数,平局场数,进球数,被进球数
}team[30];    
bool cmp(node a,node b)             //自定义的按照指定方式排序的函数
{
	if(a.points>b.points)     
		return 1;                 //比较得分 
	if(a.points<b.points)
		return 0;
	if(a.scored-a.allowed>b.scored-b.allowed)
		return 1;                                       //比较进球数和被进球数之差 
	if(a.scored-a.allowed<b.scored-b.allowed)
		return 0;
	if(a.scored>b.scored)
		return 1;                      //比较得分数 
	if(a.scored<b.scored)
		return 0;
	if(a.name.compare(b.name)<0)//队伍名称字典序a<b 
		return 1;
	return 0;
}
void update(string ss,int p,int s,int a)    //自定义计算函数,ss为涉及的队伍名,p为得分,s为进球数,a为被进球数
{
	for(int i=0;i<n;i++)
		if(team[i].name==ss)      
		{
			team[i].points+=p;       //得分累加1,3,0
			team[i].scored+=s;       //进球数累加
			team[i].allowed+=a;     //被进球数累加
			if(p==3)
				team[i].wins++;     //胜场数累加
			else if(p==1)
				team[i].draws++;       //平局场数累加
			else if(p==0)
				team[i].losses++;        //失败场数累加
			break;
		}
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int T;
	cin>>T;
	for(int t=1;t<=T;t++)
	{
		cin>>n>>m;
		for(int i=0;i<n;i++)
		{
			cin>>team[i].name;
			team[i].points=team[i].wins=team[i].losses=team[i].draws=team[i].scored=team[i].allowed=0;                  //初始的所有数据都为0
		}
		for(int i=0;i<m;i++)      //借助循环计算所有队伍得分数据
		{
			string a,b;
			int c,d;
			cin>>a>>c>>b>>d;    //输入方式为《国家1》《得分》《国家2》《得分》
			if(c>d)
			{
				update(a,3,c,d);    
				update(b,0,d,c);
			}
			else if(c==d)
			{
				update(a,1,c,d);
				update(b,1,d,c);
			}
			else if(c<d)
			{
				update(a,0,c,d);
				update(b,3,d,c);
			}
		}
		sort(team,team+n,cmp);     //按照指定要求排序结构体,达到积分表的效果
		printf("Group %d:\n",t);
		for(int i=0;i<n;i++)
			printf("%s %d %d %d %d %d %d\n",team[i].name.c_str(),team[i].points,team[i].wins,team[i].losses,team[i].draws,team[i].scored,team[i].allowed);  //积分表格式 
		printf("\n"); 
	}
	return 0;
}