7月22到7月27记录(STL专场)

 前言

    这周与上周四五全是STL,学完就用,真的我谢谢你。

 A-演唱会

Description

一个特殊的节日,zyl 举办了一场演唱会,他想要规划一下演唱会的曲目。

根据同学的要求,他要从 n 首歌(编号 1∼n)中选出 m 首加入演唱会歌单。

选择的规则很简单,班上有 a 名学生(不包括 zyl),学号为 1∼a。zyl 会按照学号统计每位同学从每首歌中得到的快乐值,记为 hi,j​。一首歌的「欢乐度」是它所给予其他所有同学的「快乐值」总和。

巧妙的是,由于歌曲风格迥异,同一个学生一定会从不同的歌中会收获不同的快乐值,且不会有任何两首歌的欢乐度相同

zyl 选出欢乐度最高的 m 首歌,并将它们按欢乐度从大到小排好序。

但 zyl 注意到了她的快乐值…

无论如何,zyl 一定会把她最喜欢的歌放进歌单(她获得快乐值最高的歌即为她最喜欢的歌)!
如果她最喜欢的歌之前已经在歌单中,那么 zyl 会把这首歌提到歌单的第一个位置(即,仅将该歌曲的位置变为第一位,其余歌曲的相对位置不变);但如果不在,zyl 则会把已经选择好的歌单里的最后一首歌给删掉。然后把她最喜欢的曲目放在歌单的最后。

现在 zyl 将统计的快乐值数据和她的学号交给你,请你帮他列出演唱会的歌单。

Input

输入共 a+1 行。

第一行共四个整数 n,m,a,b,分别代表待选的歌的数量,需要选出的歌的数量,班上的人数,她的学号。
接下来 a 行,每行 n 个整数,第 i+1 行第 j 个数代表学号为 i 的学生从第 j 首歌收获的快乐值 hi,j​。

Output

输出共一行用空格隔开的 m 个整数,依次代表演唱会的歌单上的歌的编号。

Sample 1

InputcopyOutputcopy
4 2 3 2
2 4 3 1
1 2 3 4
2 3 4 1
3 4

Hint

样例 1 解释

按照欢乐度排序后靠前的两道是 3,23,2,但由于她最喜欢的歌是 44,不在歌单里,于是将 22 从歌单里删除,之后将 44 放在最后。最后的歌单为 3,43,4。

数据规模与约定

对于 100%100% 的数据,1≤m≤n≤10^5,1≤b≤a≤100。0≤ℎ≤10^6,0≤hi,j​≤10^6。

测试点编号nmahi,j​
1∼21∼2≤5≤5=1=1≤5≤5≤10000≤10000
3∼43∼4≤1000≤1000=n≤100≤100≤10000≤10000
5∼65∼6≤1000≤1000≤1000≤1000=1=1≤10000≤10000
7∼97∼9≤1000≤1000≤1000≤1000≤100≤100≤10000≤10000
1010≤105≤105≤105≤105≤100≤100≤106≤106

详解

#include<bits/stdc++.h>
using namespace std;
struct song{
	int id,k;
}h[100005];

bool cmp(song a,song b){
	return a.k>b.k;
}
int main()
{
	int n,m,a,b;
	int max=0,max1=0;
	scanf("%d %d %d %d",&n,&m,&a,&b);
	for(int i=1;i<=a;i++){
		for(int j=1;j<=n;j++){
			h[j].id=j;
			int x;
			scanf("%d",&x);
			if(i==b){
				if(x>max){
					max=x;
					max1=j;
				}
			}
			h[j].k+=x;
		}
	}
	sort(h+1,h+n+1,cmp);
	int ret=0;
	for(int i=1;i<=m;i++){
		if(h[i].id==max1){
			ret=1;
			break;
		}
	}
	if(ret==1){
		printf("%d",max1);
		for(int i=1;i<=m;i++){
			if(h[i].id!=max1)
			printf(" %d",h[i].id);
		}
	}
	else{
		for(int i=1;i<m;i++){
			printf("%d ",h[i].id);
		}
		printf("%d",max1);
	}
}

思路步骤

1.记录每首歌的欢迎值的和与zyl的;

2.排序;

3.zyl喜欢的是否在前m个(ret=0/1);

4.分情况输出。
 


个人问题(上榜原因)


1.最经典的struct;

2.较难落实思路(结构体的普遍问题)

B-狼人杀

“狼人杀”的原型是上世纪八十年代末,莫斯科大学心理学系的迪米特里·达维多夫发明了一种警察与杀手互猜身份的游戏,也就是“杀人游戏”。“杀人游戏”从一开始就只有核心规则得到了确定,本身是一款开源游戏。1990年以后,“杀人游戏”逐渐传播到了欧洲,随后到了美国,在每个不同的国家和地区都根据各自文化背景“演化”出了新的内容。
大哲是一个忠实的狼人杀爱好者,而且是高手中的高手。由于她过于擅长各类套路,并且具备敏锐的直觉与极强的心理素质,甚至还是一个心理学博士,她的朋友逐渐失去了游戏体验。为了照顾她的朋友,她决定制定一种不靠计谋、不用推理,全靠强运的“杀法”:
游戏玩家围成一个圈,从指定的第一个人开始数数,数到第 m 个人时,那个人就会被处死。之后从被处死的人的后一个人开始数数,再数到第 m 个人处死......依此方法不断杀死玩家。假如说玩家有好人与坏人两种身份,每种身份各 n 人,试问如何安排这些人的座位,能使得在处死 n 人后,剩下的 n 人都是好人

Input

多组数据,每组数据输入:好人和坏人的人数n(<=32767)、步长m(<=32767);

Output

对于每一组数据,输出2n个大写字母,‘G’表示好人,‘B’表示坏人,50个字母为一行,不允许出现空白字符。相邻两组输出之间有一个空行隔开

Sample

InputcopyOutputcopy
 
2 3 2 4
 
GBBG BGGB 

详解

#include<bits/stdc++.h>
using namespace std;
 int n,m;
char x[70000];
int main()
{
	
	while(cin>>n>>m)
	{
		 int k=0,f=0;
	    for( int i=0;i<2*n;i++) 
		    x[i]='G';//全好
	    for( int i=0;;i++){
		    if(i==2*n) i=0;//循环
		    if(x[i]!='B') k++;//杀过的人数的时候忽略
		    if(x[i]!='B'&&k==m){//没被杀并且刚好是第m个
			f++;//
			x[i]='B';//
			k=0;//重新数
		    }
		    if(f==n) break; 
	    }
	    for(int i=0;i<2*n;i++){
		    cout<<x[i];
		    if(i!=2*n-1&&(i+1)%50==0) cout<<endl;
	    }
	cout<<endl<<endl;
	}
	return 0;
}

思路步骤

1.挑坏人杀(B),先全赋值为好。

2.跳过杀过的;

3.确定符合条件(K,还是G);

4.坏人+1;

5.循环到F=N;
 


个人问题(上榜原因)


1.最经典的约瑟夫环;

2.卡了1小时看了七八种题解才解决。

C-中位数

Description

给定一个长度为 N 的非负整数序列 A,对于前奇数项求中位数。

Input

第一行一个正整数 N。

第二行 N 个正整数A 1…N​。

Output

共 ⌊2N+1​⌋ 行,第 i 行为 A1…2i−1​ 的中位数。

Sample 1

InputcopyOutputcopy
7
1 3 5 7 9 11 6
1
3
5
6

Sample 2

InputcopyOutputcopy
7
3 1 5 9 8 7 6
3
3
5
6

Hint

对于 20%20% 的数据,N≤100;

对于 40%40% 的数据,N≤3000;

对于 100%100% 的数据,1≤N≤1000000≤Ai​≤1^09。

详解

#include<bits/stdc++.h>
using namespace std;
int main(){
	priority_queue<int> max;
	priority_queue<int,vector<int>,greater<int> > min;
	int i,n,num,mid;
	cin>>n;
	cin>>num;
	mid=num; cout<<mid<<endl;
	for(i=2;i<=n;i++){
		cin>>num;
		if(num>mid) min.push(num);
		else max.push(num);
		if(i%2){
			while(max.size()!=min.size())
			if(max.size()>min.size()){
				min.push(mid);
				mid=max.top();
				max.pop();
			}
			else{
				max.push(mid);
				mid=min.top();
				min.pop();
			}
		cout<<mid<<endl;	
		}
	}
	
}

思路步骤

1.第一个无脑中位数;

2.比大小放入队列queue;

3.输入2次(偶次)进行一次输出;{

   1.一大一小(长度相同)输出上一个;

   2.这次放入了同一个(长度不同)长的输出top,为中位数,上一个中位数放入另一个队列

}
 


个人问题(上榜原因)


1.我心中最好的队列题;

2.用了大部分技巧;

D- Cites and States S

Description

Farmer John 有若干头奶牛。为了训练奶牛们的智力,Farmer John 在谷仓的墙上放了一张美国地图。地图上表明了每个城市及其所在州的代码(前两位大写字母)。

由于奶牛在谷仓里花了很多时间看这张地图,他们开始注意到一些奇怪的关系。例如,FLINT 的前两个字母就是 MIAMI 所在的 FL 州,MIAMI 的前两个字母则是 FLINT 所在的 MI 州。
确切地说,对于两个城市,它们的前两个字母互为对方所在州的名称。

我们称两个城市是一个一对「特殊」的城市,如果他们具有上面的特性,并且来自不同的州。对于总共 N 座城市,奶牛想知道有多少对「特殊」的城市存在。请帮助他们解决这个有趣的地理难题!

Input

输入共 N+1 行。

第一行一个正整数 N,表示地图上的城市的个数。
接下来 N 行,每行两个字符串,分别表示一个城市的名称(2∼10 个大写字母)和所在州的代码(22 个大写字母)。同一个州内不会有两个同名的城市。

Output

输出共一行一个整数,代表特殊的城市对数。

Sample 1

InputcopyOutputcopy
6
MIAMI FL
DALLAS TX
FLINT MI
CLEMSON SC
BOSTON MA
ORLANDO FL
1

Hint

数据规模与约定

对于 100%100% 的数据,1≤N≤2×10^5,城市名称长度不超过 10。

详解

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int num,i,sun=0,m=2e5+5;
    map<int,int>n[m];
	cin>>num;
	for(int i=0;i<num;i++){
		string a,b;
	    cin>>a>>b;
	    int c=(a[0]-'A'+1)*26+(a[1]-'A'+1);
		int d=(b[0]-'A'+1)*26+(b[1]-'A'+1);
	    if(c==d) continue;
	    n[c][d]++;
		sun+=n[d][c];	
		
	}
	cout<<sun<<endl;
}

思路步骤

1.记录前后两次的字符(数字化)

2.记录这种情况出现次数

3.加上对应情况的次数;
 


个人问题(上榜原因)


1.运用了关键技巧数字化记录;

2.难想到这种思路;

E-产生冠军

Description

有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。
球赛的规则如下:
如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。
如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。
根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。

Input

输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。如果n为0,则表示输入结束。

Output

对于每个选手群,若你判断出产生了冠军,则在一行中输出“Yes”,否则在一行中输出“No”。

Sample

InputcopyOutputcopy
3
Alice Bob
Smith John
Alice Smith
5
a c
c d
d e
b e
a d
0
Yes
No

详解

#include<bits/stdc++.h>
using namespace std;
signed main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
  long long n,i;
	while(1){
		cin>>n;
		 if(n==0) break;
	     map<string,int> c,l;
	   	for(i=0;i<n;i++){
	   	  string a,b;
	   	  cin>>a>>b;
	   	  c[a]++; c[b]++;
	   	  l[b]++;
	    }
	    long long lc=(long long)c.size();
	    long long ll=(long long)l.size();
	    if(lc-ll==1)
	  cout<<"Yes"<<endl; 
	  else 	cout<<"No"<<endl;
	}
	
}


个人问题(上榜原因)


1.当天未作出;

2.思路独特;

F-Make Majority

Description

给定一个序列 [a1,…,an],其中每个元素 ai 要么是 0,要么是 1。你可以对该序列应用多个(可能为零)操作。在每次操作中,你选择两个整数 1≤l≤r≤|a|(其中 |a| 是 a的当前长度),并用单个元素 x替换 [al,…,ar],其中 x 是 [al,…,ar]的大多数。

这里,对于由 00 和 11 组成的序列,其大多数定义如下:假设序列中有 c0 个零和 c1 个一。

  • 如果 c0≥c1,则大多数是 0。
  • 如果 c0<c1,则大多数是 1。

例如,假设 a=[1,0,0,0,1,1]。如果我们选择 l=1,r=2,则结果序列将是 [0,0,0,1,1]]。如果我们选择 l=4,r=6,则结果序列将是 [1,0,0,1]。

确定是否可以通过有限次操作得到 a=[1]。

输入

每个测试包含多个测试用例。第一行包含测试用例的数量 t(1≤t≤41*0^4)。接下来是测试用例的描述。

每个测试用例的第一行包含一个整数 n(1≤n≤⋅10^5)。

每个测试用例的第二行包含一个由 00 和 11 组成的字符串,描述序列 a。

保证所有测试用例中 n 的总和不超过 2⋅1052⋅105。

输出

对于每个测试用例,如果可以得到 a=[1],则打印 YES。否则,打印 NO。你可以以任何形式(大写或小写)输出答案。例如,字符串 yEs、yes、Yes 和 YES 都将被视为肯定回答。

示例

InputcopyOutputcopy
5
1
0
1
1
2
01
9
100000001
9
000011000
No
Yes
No
Yes
No

注意

在示例的第四个测试用例中,初始时 a=[1,0,0,0,0,0,0,0,1]�=[1,0,0,0,0,0,0,0,1]。一组有效的操作序列是:

  1. 选择 l=2,r=8并应用该操作。 a变为 [1,0,1][1,0,1]。
  2. 选择 l=1,r=3 并应用该操作。 a 变为 [1][1]。

详解

#include<bits/stdc++.h>
using namespace std;
signed main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int num;
    cin>>num;
	while(num--){
	    int n,zero=0,one=0;
	    bool last=false;
	    cin>>n;
	    for(int i=1;i<=n;i++){
	    	char a;
	    	cin>>a;
	    	int num=a-'0';
	    	if(num==0){
	    		last=true;
			}
			else if(num!=0&&last){
				last=false;zero++;one++;
			}
			else if(num!=0){
				one++;
			}
		}
	    if(last) zero++;	
		if(zero>=one) cout<<"No"<<"\n";
		else cout<<"Yes"<<"\n";
		
    }
}
		

————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/2301_81939891/article/details/140475871

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值