8. 3和8.4暑假集训

昨天又又又又那个了..

今天上午写了一道1600分的题,写了快2个小时也没整出来....

然后又做了一道1500分异或的题,又没出来

下午打航电多校,只出了一题..其他的题直接离谱...

Problem - 1348C - Codeforces

这题我想的极其复杂.但是大体上思路是正确的

分了字典序最小的字母大于k等于k和小于k的情况.然后还考虑了其他特殊的情况

麻烦死了..

cpp 复制代码
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
#include <list>
using namespace std;
typedef  long  long ll ;
typedef  unsigned long  long ull ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
int t; 
int main(){
	scanf("%d",&t);
	
	while(t--){
		
		int n,k;
		scanf("%d%d",&n,&k);
		string s;
		cin>>s;
		vector<int>a(30);
		int num=0;
		for(int i=0;i<s.length();i++){
			a[s[i]-96]++;
			if(a[s[i]-96]==1)num++;
		}
		
		
		int cnt;
		int pos;
		for(int i=1;i<=27;i++){
			if(a[i]!=0){
				cnt=a[i];
				pos=i;
				break;
			}
		}
		
		if(k==1){
			for(int i=1;i<=27;i++){
				for(int j=1;j<=a[i];j++){
					cout<<char(i-1+'a');
				}
			}
			printf("\n");
			continue;
		}
		
		
		if(num==1){
			if(n%k==0){
				n=n/k;
			}else{
				n=n/k+1; 
			}
			int flag=0;
			for(int i=1;i<=27;i++){
				if(flag)break;
				if(a[i]!=0){
					for(int j=1;j<=n;j++){
						cout<<char(i-1+'a');
						flag=1;
					}
					
				}
			}
			printf("\n");
			continue;
		}
		
		
		if(n==k){
			for(int i=27;i>=1;i--){
				if(a[i]!=0){
					cout<<char(i-1+'a');
					break;
				}
			}
			printf("\n");
			continue;
		}
		
		
		if(cnt==k){
			cout<<char(pos-1+'a');
			
			if(num-1>=2){
				for(int i=pos+1;i<=27;i++){
				for(int j=1;j<=a[i];j++){	
					cout<<char(i-1+'a');
				}				
				}
			}else{
				for(int i=pos+1;i<=27;i++){
				for(int j=1;j<=a[i];j=j+k){	
					cout<<char(i-1+'a');
				}				
				}
			}
			
			printf("\n");
			continue;
		}
		
		
		if(cnt>k){ 
			for(int i=1;i<=cnt-k+1;i++){
				cout<<char(pos-1+'a'); 
			} 	
				
		if(num-1>=2){
			
			for(int i=pos+1;i<=27;i++){
				for(int j=1;j<=a[i];j++){	
					cout<<char(i-1+'a');
				}				
				}
			printf("\n");
			continue;
		}else{
			for(int i=pos+1;i<=27;i++){
				for(int j=1;j<=a[i];j++){	
					cout<<char(i-1+'a');
				}				
				}
		} 
		
	}
		if(cnt<k){
			int flag=0;
			for(int i=pos+1;i<=27;i++){
				if(flag)break;
				for(int j=1;j<=a[i];j++){
					cnt++;	
					if(cnt==k){
						cout<<char(i-1+'a');
						flag=1;
						break;
					}
				}				
			}
			
			printf("\n");
		}
		
	
}
	return 0;
}

 

感觉写的没啥问题.但就是没过,标准答案是真的简单!!(当我写到这里时已经过了快24小时了..)

还有就是我不会string的排序...

现在会了...sort(s.begin(),s.end())

1.如果字典序最小的字母的数量小于k,那么直接输出第k个字母即可

2.如果字典序最小的字母的数量大于等于k,输出一个s[0],如果s[k]==s[n-1]的话就k组均分

否则就全部加到第一组上

当时我考虑了字典序最小的字母的数量大于等于k的情况分了2种:(只有一种字母的情况已经特殊考虑了)

1.等于k:如果s[k]到s[n-1]的字母种类大于1,就全部输出,否则说明种类等于1就均分

2大于k:这个情况我考虑错了.一开始我想着把第一个字母均分为k组

其实最优的是把k-1个字母分成k-1组,然后第一组接后面的全部

cpp 复制代码
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
#include <list>
using namespace std;
typedef  long  long ll ;
typedef  unsigned long  long ull ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
int t;
int main(){
	scanf("%d",&t);
	while(t--){
		int n,k;
		scanf("%d%d",&n,&k);
		string s;
		cin>>s;
		sort(s.begin(),s.end());
		if(s[0]!=s[k-1]){
			cout<<s[k-1]<<endl;
		}else{
			cout<<s[0];
			if(s[k]!=s[n-1]){
				for(int i=k;i<=n-1;i++){
					cout<<s[i];
					
				} 
			}else{
				for(int i=k;i<=n-1;i=i+k){
					cout<<s[i];
				}
			}
			cout<<endl;
		}
	}


	return 0;
}

 

Problem - 1419D2 - Codeforces

这题纯贪心....

我吐了我写了快2个小时二分,最后也没整出来..结果是纯贪心?

但是仔细想一想确实是这样的...

首先排序

cpp 复制代码
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
#include <list>
using namespace std;
typedef  long  long ll ;
typedef  unsigned long  long ull ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
const int N=1e5+5;
int n; 
int main(){
	vector<int>a,b(N);
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		a.push_back(x);
	}
	sort(a.begin(),a.end());
	int id=0;
	for(int i=1;i<n;i=i+2){
		b[i]=a[id++]; 
	}
	for(int i=0;i<n;i=i+2){
		b[i]=a[id++]; 
	}
	int ans=0;
	for(int i=1;i<n-1;i++){
		if(b[i-1]>b[i]&&b[i]<b[i+1]) ans++;
	}
	
	printf("%d\n",ans);
	for(int i=0;i<n;i++){
		cout<<b[i]<<" ";
	}

	return 0;
}

 

我们预设一个vector,然后vector的偶数项为最小的前i项,然后剩余的项为奇数项

如果a[i-1]>a[i]&&a[i]<a[i+1],答案就++

Problem - 1487C - Codeforces

这题还是很有意思的..

一道规律题.手玩几个样例可以发现奇数队伍输赢输赢输赢最后是可以平局的

偶数队伍,前n/2赢,n/2平,后面输是可以平局的,2的时候特判一下即可

cpp 复制代码
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<stack>
#include<deque>
#include<vector>
#include<map>
#include<set>
#include <utility>
#include <list>
using namespace std;
typedef  long  long ll ;
typedef  unsigned long  long ull ;
#define pii pair<int,int>
const int inf = 0x3f3f3f3f;//106110956
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
void print(__int128 num) {
	if(num) {
		print(num/10);
		putchar(num%10+'0');
	}
}
int t;
int main(){
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		if(n==2){
			printf("0\n");
			continue;
		}
		
		if(n&1){
			for(int i=1;i<=n-1;i++){
				int cnt=0;
				for(int j=1;j<=n-i;j++){
					cnt++;
					if(cnt%2==1){
						printf("1 ");
					}else{
						printf("-1 ");
					}
					
				}
			}
		}else{
			int now=n/2;
			for(int i=1;i<=n-1;i++){
				for(int j=1;j<=n-i;j++){
					if(j<now){
						printf("1 ");
					}
					if(j==now)printf("0 ");
					if(j>now)printf("-1 ");
				}
			}
		}
		printf("\n");
	}
	
	return 0;
}

 

Problem - 268C - Codeforces

远古题目..

题目大概意思是给你n和m,使0<=x<=n&&0<=y<=m,然后让你找最多的点使得任意2个点之间的距离不为整数...

因为题目的n和m的范围很小,可以枚举起点然后在遍历所有点复杂度为(n^4),应该能过。

但是感觉不太靠谱...想了一会没思路看了答案..

发现y=-m/n+m这条线是最优的,起点为(0,m)终点为(n,0)

因为相邻2点的横纵坐标差为1,距离为根号2

Problem - 1630A - Codeforces

这题确实挺离谱的为啥才是1500分题目?

我们可以发现i和n-i-1异或为0(n为2的倍数,这个怎么发现的?)

所以如果最后答案为0的

cpp 复制代码
if(k==0){
			for(int i=0;i<n/2;i++){
				printf("%d %d\n",i,n-i-1);
			}			

考虑答案k<n-1的情况

我们发现k&n-1为k,这其实很好想,n-1的二进制全都是1

然后我们在根据上面构造0

但是n-1和k用了

所以我们不能用0和n-k+1了,又0&n-k+1为0

代码如下:

注意特判因为我们不知道k是否小于n/2,所以i!=k和i!=n-k-1都需要特判

cpp 复制代码
else if(k<n-1){
			printf("%d %d\n",k,n-1);
			printf("0 %d\n",n-k-1);
			for(int i=1;i<n/2;i++){
				if(i!=k&&i != n-k-1){
					printf("%d %d\n",i,n-i-1);
				}
			}

然后就是k=n-1的情况了

我真的吐了怎么这么难构造

我们发现n-1&n-2为n-2,所以我们需要构造1

又1&3=1

所以n-1就构造出来了

又我们n-4和0配不了队了而且n-4&0=0

所以代码如下

cpp 复制代码
printf("%d %d\n",n-1,n-2);
			printf("1 3\n");
			printf("%d 0\n",n-4);
			for(int i=2;i<n/2;i++){
				if(i!=3){
					printf("%d %d\n",i,n-i-1);
				}
			}

然后还有一个特例

4不能组成3

太麻烦了吧...

相关推荐
一点媛艺3 小时前
Kotlin函数由易到难
开发语言·python·kotlin
姑苏风3 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
奋斗的小花生4 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
pianmian14 小时前
python数据结构基础(7)
数据结构·算法
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程5 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
UestcXiye6 小时前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
Chrikk6 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*6 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go