2021GPLT天梯赛 L1L2题解

文章目录

L1-1 人与神

#include
using namespace std;
int main()
{
	printf("To iterate is human, to recurse divine.");
 } 

L1-2 两小时学完C语言

#include
using namespace std;
int main()
{
	int n,m,k;
	cin >> n >> m >> k; 
	cout<<n-(m*k);
	return 0; 
}

L1-3 强迫症

#include
using namespace std;
int main()
{
	string a;
	cin >> a;
	if(a.length()==6)
	{
		cout<<a[0]<<a[1]<<a[2]<<a[3]<<"-"<<a[4]<<a[5]; 
	}
	else
	{
		int m;
		m = (a[0]-'0')*10+a[1]-'0';
		if(m>=22) cout<<"19";
		else cout<<"20";
		cout<<a[0]<<a[1]<<"-"<<a[2]<<a[3];
	}
	return 0;
}

L1-4 降价提醒机器人

#include
using namespace std;
int main()
{
	double p;
	int n,m;
	cin >> n>> m;
	while(n--)
	{
		cin>>p;
		if(p<m)
		{
			printf("On Sale! %.1lf\n",p);
		}
	}
	return 0;
}

L1-5 大笨钟的心情

#include
using namespace std;
int main()
{
	int time[25];
	for(int i = 0;i<24;i++)
		cin >> time[i];
	int n;
	while(scanf("%d",&n)&&n>=0&&n<24)
	{
		if(time[n]>50)
		{
			cout<<time[n]<<" Yes"<<endl;
		}
		else
		{
			cout<<time[n]<<" No"<<endl;
		}
	}
	return 0;
}

L1-6 吉老师的回归

思路:用strstr函数判断子串

#include
#include 
int main()
{
	int n,m,flag = 0,count = 0;
	char s[200][505];
	scanf("%d %d",&n,&m); 
	getchar();
	for(int i = 0;i<n;i++)
	{
		gets(s[i]);
	} 
	for(int i = 0;i<n;i++)
	{
		if((strstr(s[i],"qiandao")!=NULL)||(strstr(s[i],"easy")!=NULL))
			continue;
		count++;
		if(count>m)
		{
			printf("%s\n",s[i]);
			flag = 1;
			break;
		}
	}
	if(!flag)
	{
		printf("Wo AK le\n");
	}
	return 0;
}

L1-7 天梯赛的善良

思路:用sort函数排序,然后两端查找最大值和最小值的个数

#include
#include
using namespace std;
long long a[100005];
int main()
{
	int n;
	cin >> n;
	for(int i = 0;i<n;i++) cin >> a[i];
	sort(a,a+n);
	long long mins = 0,minsum =0,maxsum = 0,maxs = 0;
	for(int i = 0;i<n;i++)
	{
		if(a[i]==a[0])
		{
			mins++;
			minsum = a[0];
		}
	}
	for(int i = n-1;i>=0;i--)
	{
		if(a[i]==a[n-1])
		{
			maxs++;
			maxsum = a[n-1];
		}
	}
	cout<<minsum<<" "<<mins<<endl;
	cout<<maxsum<<" "<<maxs<<endl;
	return 0;
}

L1-8 乘法口诀数列

思路:因为只需要两个数相乘得出结果,所以分为大于10还有小于十两方面处理就行

#include
using namespace std;
int main()
{
	int n,in = 2,i = 0;
	int a[10005];
	cin >> a[0] >> a[1] >> n;
	while(in<n)
	{
		int c = a[i+1]*a[i];
		if(c<10)
			a[in++] = c; 
		else
		{
			a[in++] = c/10;
			a[in++] = c%10;
		}
		i++;
	}
	for(int i = 0;i<n;i++)
	{
		cout<<a[i];
		if(i!=n-1) cout<<" ";
	}
	return 0;
}

L2-1 包装机

思路:把筐比成栈,把轨道比成队列,注意处理好堆栈为空还有队列为空的情况

#include
#include 
#include
using namespace std;
int main()
{
	char a[110][1005];
	int b[110];
	stack<char> s;
	int n,m,k,c;
	memset(b,0,sizeof(b));
	cin >> n >> m >> k;
	for(int i = 1;i<=n;i++){
		for(int j = 0;j<m;j++)
		{
			cin >> a[i][j];
		}
	}
	while(scanf("%d",&c)&&c!=-1)
	{
		if(c==0)
		{
			if(s.size()==0) continue;
			printf("%c",s.top());
			s.pop();
		}
		else
		{
			if(b[c]>=m) continue;
			if(s.size()>=k)
			{
				printf("%c",s.top());
				s.pop();
			}
			s.push(a[c][b[c]++]);
		}
	}
	return 0;
 } 

L2-2 病毒溯源

思路:题目和功夫传人差不多,都是要求寻找到根结点,然后进行dfs搜索,选出序列最长的,难点是找出序列最长的那个,其实序列最长其实可以用vector直接进行比较大小,而且vector也可以直接赋值,

#include
#include
#include
using namespace std;
int p[100010],visit[100010];
int n;
vector<int> a,t;
int maxs = 0;
void DFS(int root,int len)
{
	if(len>maxs)
	{
		maxs = len;
		a = t;
	}
	if(len==maxs&&a>t) a = t;                  //vector可以进行大小比较还有赋值
	for(int i = 0;i<n;i++)
	{
		if(p[i]==root&&!visit[i])
		{
			visit[i] = 1;
			t.push_back(i);
			DFS(i,len+1);
			t.pop_back();
		}
	}
}
int main()
{
	cin >> n;
	memset(visit,0,sizeof(visit));
	for(int i = 0;i<n;i++) p[i] = i;
	for(int i = 0;i<n;i++)
	{
		int k;
		cin >> k;
		for(int j = 0;j<k;j++)
		{
			int c;
			cin >> c;
			p[c] = i;
		}
	}
	int root;
	for(int i= 0;i<n;i++) 
	{
		if(p[i]==i) root = i;
	}
	t.push_back(root); 
	visit[root] = 1;
	DFS(root,1);
	cout<<a.size()<<endl;
	for(int i= 0;i<a.size();i++)
	{
		if(!i) cout<<a[i];
		else cout<<" "<<a[i];
	}
	return 0;
}

L2-3 清点代码库

思路:重复的数据可以用map或者set进行去重,但是由于数据有并列还有需要统计个数,所以应该用map处理数据,用个数出来统计数据,用vector作为map的键(没想到vector还能作为键值…赛后看网上补题学到的,map数据处理好后,因为要求排序输出,所以用一个结构体装入map的数据,用sort排序输出

#include
#include
#include
#include
using namespace std;
int n,m;
map<vector<int>,int> mp;
struct node{
	vector<int> v;
	int cnt;
}a[100010];
int cmp(struct node a,struct node b)
{
	if(a.cnt==b.cnt) return a.v<b.v;
	else return a.cnt>b.cnt;
}
int main()
{
	scanf("%d %d",&n,&m);
	for(int i = 0;i<n;i++)
	{
		vector<int> v;
		for(int j = 0;j<m;j++)
		{
			int c;
			scanf("%d",&c);
			v.push_back(c);
		}
		if(mp.count(v)) mp[v]++;
        else mp[v]=1;
	}
	int k = 0;
	for(auto it = mp.begin();it!=mp.end();it++)
	{
		a[k] = {it->first,it->second};
		k++;
	}
	sort(a,a+k,cmp);
	printf("%d\n",k);
	for(int i = 0;i<k;i++)
	{
		printf("%d",a[i].cnt);
		for(int j = 0;j<a[i].v.size();j++)
			printf(" %d",a[i].v[j]);
		printf("\n");
	}
	return 0;
}

L2-4 哲哲打游戏

思路:很简单的题目,用vector存入每个结点的支线,每次走到一个新的存档点,用更新当前结点的路径path,遇到1就用一个数组储存存档点,然后打印就行。

#include
#include 
using namespace std;
vector<int> g[100010];
int n,m;
int len[100010];
int path = 1;
int main()
{
	cin >> n >> m;
	for(int i = 1;i<=n;i++)
	{
		int k;
		cin >> k;
		while(k--)
		{
			int c;
			cin >> c;
			g[i].push_back(c);
		}
	}
	while(m--)
	{
		int x,y;
		cin >> x >> y;
		if(x==1)
		{
			len[y] = path;
			cout<<path<<endl;
		}
		else if(x==0)
		{
			path = g[path][y-1];
		}
		else if(x==2)
		{
			path = len[y];
		}
	}
	cout<<path<<endl;
	return 0;
 } 

结语

2021GPLT天梯赛 L1L2题解_第1张图片
赛后补题,希望能帮助到别人,最最重要的是一起交流学习啊

你可能感兴趣的:(算法,数据结构,dfs)