返校康复训练

感觉自己在家里面待了几天...脑子好像费了(其实也没有吧)就是没有那么活跃了,那么就开始康复训练了!!

周一到周三vp了3场,感觉自己好菜....不会啊....然后发现补题也补的好艰难啊!!!

/(ㄒoㄒ)/~~

Problem - A - Codeforces

div3的A题,md想了快20多分钟才出来,真的菜..

当时读题也读的异常艰难...

自己也写的异常麻烦啊..直接写了4个循环...真服了我自己了...

赛后直接问lb,然后他的做法挺简单的,首先打表列出需要的字符,然后在遍历列和行即可

如果找到了就break跳出这列

#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>
#include<unordered_set>
#include<unordered_map>
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 n,m;
char a[25][25];
vector<int>s[10];
int main(){
	scanf("%d",&t);
	while(t--){
	
		for(int i=1;i<=4;i++)s[i].clear();
		
		scanf("%d%d",&n,&m);
		
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				cin>>a[i][j];	
				if(a[i][j]=='v')s[1].push_back(j);
				if(a[i][j]=='i')s[2].push_back(j);
				if(a[i][j]=='k')s[3].push_back(j);
				if(a[i][j]=='a')s[4].push_back(j);
				
			}
		}
		
		sort(s[1].begin(),s[1].end());
		sort(s[2].begin(),s[2].end());
		sort(s[3].begin(),s[3].end());
		sort(s[4].begin(),s[4].end());
		
		if(s[1].size()==0){
			printf("NO\n");
			continue;
		}
		
		int pos=s[1][0];
		
		int now;
		
		now=pos;
		
		for(auto x:s[2]){
			if(x>pos){
				pos=x;
				break;
			}
		}
		
		if(pos==now){
			printf("NO\n");
			continue;
		}
		
		
		now=pos;
		
		for(auto x:s[3]){
			if(x>pos){
				pos=x;
				break;
			}
		}
		
		if(pos==now){
			printf("NO\n");
			continue;
		}
		
		
		now=pos;
		
		for(auto x:s[4]){
			if(x>pos){
				pos=x;
				break;
			}
		}
		
		if(pos==now){
			printf("NO\n");
			continue;
		}
		
		printf("YES\n");
		
	} 

	return 0;
	
}

 

B题直接秒了,简单的很...

Problem - C - Codeforces

这个C题还是很有意思的:

判读旋转过后是否是对称..,一开始我想直接图像是否对称但是不好判读,我还百度了一下,对称有选择对称和中心对称...

然后我就想别的方法了,然后就有思路了

我们用mp[i]存旋转前高度为i的木块的数量,可以发现旋转后高度的范围为1到n,还有宽度为1且高度为i的木块的数目为a[i]-a[i+1],如果等于mp[i]的话是满足条件的否则就是不满足条件的!

还有注意n为1且a[1]为1是满足条件的,其他是不满足条件的

#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>
#include<unordered_set>
#include<unordered_map>
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 n;
int a[200005];
int main(){
	scanf("%d",&t);
	
	while(t--){
		
		scanf("%d",&n);
		
		map<ll,ll>mp;
		
		for(int i=1;i<=n+5;i++)a[i]=0;
		
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			mp[a[i]]++;
		}
		
		
		int flag=1;
		
		if(n==1&&a[1]!=1){
			printf("NO\n");
			continue;
		}
		
	
		
		for(int i=1;i<=n;i++){
			
			if(a[i]-a[i+1]==mp[i]){
				continue;
			}else{
				flag=0;
				break;
			}
		}
		
		
		if(flag==0){
			printf("NO\n");
		
		}else{
			printf("YES\n");
		}
		
	}


	return 0;
}
 

D:md这题我连样例怎么来的都不知道,做不出来..赛后看了题解也没有看懂!!!

Problem - A - Codeforces

这题也花了20多分钟,真的服了自己了,还是太菜了,赛后想了想,当时我只是感觉我觉得对,就写了,连样例都没试...

一开始我只想检验样例是否合法...最后发现是错误的..

以后还得改变一下做题方法,一定要先想明白在写,如果想明白了,代码还是很好写的

1.如果是()的话无解,这点其实很好想,否则的话都有解

2.如果样例的括号是交错的,一个(,然后一个),比如这样,我们构造(((())))

如果不是交错的,我们构造()()()()

Problem - B - Codeforces

纯纯数学题,但是没出来....好伤心...

感觉还是自己畏惧了,之前自己做过这样的题,然后自己都没做出来....然后再做的时候可能就有一点畏惧了吧,也担忧自己出不来..(都是借口..)

当时思路很混乱啊....不知道怎么才是最优的..但肯定的是这题一定是贪心..

但是最后也没有贪出来...

1.要使额外需要的钱的数目最少,能肯定的是,一定要多拿价值为k的,少拿价值为1的

2.根据1,我们需要m/k张价值为k的,m%k张价值为1的

3.如果1有剩余的,我们可以用k张1来少拿一张k

3.我们额外需要拿k的张数takek= max(0,m/k-ak),额外需要拿1的张数take1=max(0,m%k-a1)

1剩余的张数 left1=max(0,a1-m%k),剩余的1能转换的k的数目 x=left1/k;

4.答案为 take1+takek-min(takek,x);

#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>
#include<unordered_set>
#include<unordered_map>
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 m,k,a1,ak;
	 cin>>m>>k>>a1>>ak;
	 int needk=m/k;
	 int need1=m%k;
	 int take1=max(0,need1-a1);
	 int left1=max(0,a1-need1);
	 int takek=max(0,needk-ak);
	 int res=min(takek,left1/k);
	 printf("%d\n",take1+takek-res);
		
	}


	return 0;
}

 

Problem - C - Codeforces

这题又没出来.../(ㄒoㄒ)/~~...

是一道博弈论的题目,但是我想的还是太简单了3...

我想的是如果1到i的话如果只有一个满足条件的话,那么Alice一定赢,但是还是我想的太简单了...

Bob赢的方式有i前面有必定赢局面或者前面没有路可以走了,‘

Alice赢的方式就是BoB输的情况了。

然后就是博弈论递推了..

我们设minn为前i的最小的值,minwin为必赢局面的最小值,

如果  x<a[i]&&x>minwin(有路并且没有必赢局面)的话,那么就一定Alice赢

#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>
#include<unordered_set>
#include<unordered_map>
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,n;
int a[300005];
int main(){
	scanf("%d",&t);
	
	while(t--){
		int n;
		scanf("%d",&n);
		
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		
		int minn=n+1;
		
		int minwin=n+1;
		
		
		int ans=0;
		
		for(int i=1;i<=n;i++){
			if(minn<a[i]&&a[i]<minwin){
				ans++;
				minwin=min(minwin,a[i]);
			}
			minn=min(minn,a[i]);
		}
		
		printf("%d\n",ans);
	
	}	
	

	return 0;
}

 

然后就是练习赛了..我只能说这是我遇到最恶心的练习赛了...

恶心死了...

登录—专业IT笔试面试备考平台_牛客网

b题就有一点难度,但是我出了.花了18分钟吧..还是挺慢的了.

感觉还是高中的概率吧..不是很难,然后就是控制精度

#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>
#include<unordered_set>
#include<unordered_map>
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 main(){
	int t;
	scanf("%d",&t);
	while(t--){
		double a1,b1,c1;
		double a2,b2,c2;
		cin>>a1>>b1>>c1;
		cin>>a2>>b2>>c2;
		
		if(a1==a2&&a1==10){
			printf("Sorry,NoBruteForce\n");
			continue;
		}
		
		if(b1==b2&&b1==10){
			printf("Sorry,NoBruteForce\n");
			continue;
		}
		
		if(c1==c2&&c1==10){
			printf("Sorry,NoBruteForce\n");
			continue;
		}
		
		a1=a1*0.1;
		a2=a2*0.1;
		b1=b1*0.1;
		b2=b2*0.1;
		c1=c1*0.1;
		c2=c2*0.1;
		
		double ans=0;
		double ping=a1*a2+b1*b2+c1*c2;
		double win=1-ping;
		
		double cnt=1;
		double x=1;
		
		while(1){
			
			double now;
			
			if(cnt==1){
				now=cnt*x*win;
			}else{
				x=x*ping; 
				now=cnt*x*win;
			}
			cnt++;
			ans=ans+now;
			
			if(now<1e-5)break;
			
		}
		
		cout<<ans<<endl;
	}
		
	
	return 0;
}


登录—专业IT笔试面试备考平台_牛客网

先不说C题,感觉c题是真的恶心啊....

d题题目很好理解..但就是没啥思路..........

还是菜啊...

正解:

从后往前和从前往后是一样的

我们用mp存每个牌的个数

然后遍历1到n,如果mp[i]不为0,我们就在枚举i到n同时维护cnt(cnt为连续的牌数)如果mp[j]>mp[j+1]就break

如果cnt>=5就继续只到mp[i]为0,否则输出No

#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>
#include<unordered_set>
#include<unordered_map>
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 n;
int a[200005];
int main(){
	
	scanf("%d",&t);
	
	while(t--){
		
		scanf("%d",&n);
		
		map<int ,int>mp;
		
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			mp[a[i]]++;
		}
		
		int flag=0;
		
		for(int i=1;i<=n;i++){
			
			if(flag){
				break;
			}
			while(mp[i]){
				
				int cnt=0;
				
				for(int j=i;j<=n;j++){
					if(mp[j]==0)break;
					mp[j]--;
					cnt++;
					if(mp[j]+1>mp[j+1])break;
				}
				
				if(cnt<5){
					printf("NO\n");
					flag=1;
				}
				
				cnt=0;
				
				if(flag){
					break;
				}
				
			}
			
		}
		
		
		if(flag){
			continue;
		}		
		printf("yes\n");
		
	}
    
	return 0;
}


登录—专业IT笔试面试备考平台_牛客网

这题我感觉是真的恶心....

都有点不想写题解了...

有两种做法:dp和贪心

dp:我们设dp[i]为形成1到i的排列所需的最少子段数目,

g[i]为i从i-1到0没有与i在一个子段的最小的数

注意j是全局变量!!!.md就是因为这个j写在for循环里面一直有个点不懂

	for(int i=1;i<=m;i++){
			
			dp[i]=min(dp[i],dp[g[i]]+1);
			
		}
	int j=1;
		
		for(int i=1;i<=n;i++){
			
			if(i!=1&&a[i]!=a[i-1]+1)j=i;
			
			if(a[i]<=m)g[a[i]]=min(g[a[i]],a[j]-1);	
			
		}

最后的dp[m]就为答案,如果dp[m]>m的话,说明无解

#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>
#include<unordered_set>
#include<unordered_map>
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 a[200005];
int main(){
	
	scanf("%d",&t);
	
	while(t--){
		
		int n,m;
 
		scanf("%d%d",&n,&m);
		
		for(int i=1;i<=n;i++){
			
			scanf("%d",&a[i]);
			
		}
		
		vector<int>dp(m+5,m+1),g(m+5,m+1);
		
		dp[0]=0;
		
		int j=1;
		
		for(int i=1;i<=n;i++){
			
			if(i!=1&&a[i]!=a[i-1]+1)j=i;
			
			if(a[i]<=m)g[a[i]]=min(g[a[i]],a[j]-1);	
			
		}
		
		for(int i=1;i<=m;i++){
			
			dp[i]=min(dp[i],dp[g[i]]+1);
			
		}
		
		
		if(dp[m]<=m){
			
			printf("%d\n",dp[m]);
			
		}else{
			
			printf("-1\n"); 
			
		}
				
	}

	return 0;
}


 贪心:

牛客练习赛 114_Unlimitedz的博客-CSDN博客

在网上找的一个方法,感觉这方法有点极限啊....

700多ms过的...如果数据再极限点的话肯定就过不了了..但是他真种做法的思想还是很好的..

 

#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>
#include<unordered_set>
#include<unordered_map>
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;

struct Node{
	int x,y;
}b[200005];

int a[200005];

bool cmp(Node s1,Node s2){
	return s1.x<s2.x;
}

int main(){
	
	scanf("%d",&t);
	
	while(t--){		
	
		int n,m;	
				
		scanf("%d%d",&n,&m);
		
		for(int i=1;i<=n;i++){
			
			scanf("%d",&a[i]);
			
		}
		
		int cnt=0;
		
		for(int i=1;i<=n;i++){
						
			if(i+1<=n&&a[i+1]==a[i]+1){
				
				int j=i;
				
				while(j+1<=n&&a[j+1]==a[j]+1){
					j++;
					
				}
				
				b[++cnt].x=a[i];
				b[cnt].y=a[j];
			
				i=j;
			
			}else{
				
				b[++cnt].x=a[i];
				b[cnt].y=a[i];
				
			}		
		}
					
		sort(b+1,b+1+cnt,cmp);
		
		int ans=0;
		int flag=0;
		int l=1;
		int r=0;
		
		for(int i=1;i<=cnt;i++){
			
			if(b[i].x>l){
				flag=1;
				break;
			}
			
			ans++;
			int j=i;
		
			while(j<=cnt&&b[j].x<=l){
				r=max(r,b[j].y);	
				j++;
			}
			
			
			if(r>=m)break;
			l=r+1;		
					
		}
			
			
		if(r<m||flag){
			printf("-1\n");
		}else{
			printf("%d\n",ans);
		}	
		
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值