第十一届山东省大学生程序设计竞赛(正式赛)

昨天下午跟队友打的这场比赛,一共出了2题,签到题7分钟出了,但是有个签到题dp我一直被卡,做不出来....然后心态有点无了....幸好队友过了一题。打了三个小时就下班了...  我发现每次比赛我被卡的时候心态都好炸裂啊....我感觉自己在队伍中得尽量不写代码,得队友来写了。不然被题卡住的时候,自己的心态太难调整了...我感觉这次省赛我们队伍应该是获得不了奖了,所以放平心态吧...让自己尽量享受这次经历吧。showmaker说:失败总是贯穿人数始终,这就是人生。我才是第一年,我还有2年的时间,在这两年的时间内,一个人可以改变很多。总之,继续坚持吧。

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

这题其实就是模拟除法运算,思路还是很好想的,就不多说了...

#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>
using namespace std;
typedef  long  long ll ;
#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');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
int n;
int k; 
int main(){
	scanf("%d%d",&n,&k);
	int ans=0;
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		ans=ans+x;
	}
	printf("%d.",ans/n);
	ans=ans%n;
	int cnt=1;
	while(cnt<=k){
		ans=ans*10;
		printf("%d",ans/n);
		ans=ans%n;
		cnt++;
	} 
	


	return 0;
}


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

这题我一眼就看出是二维背包的变形问题,但自己真的有个特别坏的毛病,遇见自己感觉做不出来的题目,自己思路就不清晰,开始乱写了...这题我状态表示很好想,但是我状态转移方程都没想明白就开始写了...(我是dp高手?(bushi)),所以一会做dp题目的时候,一定要先想明白状态表示和状态转移方程在写啊!!!还是平常做dp题目的时候,没有这个习惯啊

我们设dp[i][j]为体力为i维他命为j的时候所获得的最多金币数目

当j>h[i]&&k>=s[i]时 (注意k不能等于h[i],因为人的体力不能为0,即我们不能从dp[0][k转移来])     dp[j][k]=max(dp[j][k],dp[j-h[i]][k-s[i]]);

当j>h[i]&&j+k>=h[i]+s[i](此时k-s[i]<0即维他命不足,需要体力来补充,需要补充的为是s[i]-k)

dp[j][k]=max(dp[j][k],dp[j-h[i]-(s[i]-k)][0]);

#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>
using namespace std;
typedef  long  long ll ;
#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');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
int n,H,S;
ll h[1005],s[1005],w[1005];
ll dp[305][305];//体力为i,维他命为j的时候的最大金币数目 
int main(){
	scanf("%d%d%d",&n,&H,&S);
	
	for(int i=1;i<=n;i++){
		scanf("%lld%lld%lld",&h[i],&s[i],&w[i]);
	}
	
	ll ans=0;
	for(int i=1;i<=n;i++){
		for(int j=H;j>=h[i];j--){//体力 
			for(int k=S;k>=0;k--){//维他命 
				if(j>h[i]&&k>=s[i]){
						dp[j][k]=max(dp[j][k],dp[j-h[i]][k-s[i]]+w[i]);
						
				}else{
					if(j>h[i]&&j+k>h[i]+s[i]){
						int res=s[i]-k;
						dp[j][k]=max(dp[j][k],dp[j-h[i]-res][0]+w[i]);
					}
					
				}
				ans=max(ans,dp[j][k]);
			}
		}
	}
	
	printf("%lld\n",ans);

	return 0;
}


以后写dp题目一定要先想明白状态表示和状态转移方程在下笔啊!!!!不要再瞎写了啊!!!

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

英文题面是真的恶心啊,比赛的时候题面都读不懂啊.....

这题题目都没读懂,直接开翻译;

比赛时候没做出来,我们都感觉是搜索之类的...其实就是个思维+构造

注意:题目中第1行第n行和第1列第m列都为0;

所以我们可以让A的第一行为1,B的第n行为m,然后让A的奇数列为1(除了第n行),让B的偶数列为1(除了第一行),因为我们要使AB中原来为0的地方至少有一个为0(这里行列是等效的)

一开始我是这样想的A的所有奇数行为1,B的所有偶数行为1,这样为啥不行啊?...

比如:

000000

1111111

000000

1111111

000010

上面的例子虽然所有的偶数行为1,但是所有的1都不连通,所有AB都需要一列来联通

	#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>
	using namespace std;
	typedef  long  long ll ;
	#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');
		}
	}
	ll ex_gcd(ll a,ll b,ll& x,ll& y){
		if(b==0){
			x=1;
			y=0;
			return a;
		}
	
		ll d=ex_gcd(b,a%b,y,x);
		y=y-a/b*x;
		return d;
	}
	int n,m;
	int a[505][505];
	int b[505][505];
	string c[505]; 
	int main(){
		scanf("%d%d",&n,&m);
		
		for(int i=1;i<=n;i++){
				cin>>c[i];			
		}
		
		for(int i=1;i<=n;i++){
			for(int j=0;j<m;j++){
				if(c[i][j]=='1'){
					a[i][j+1]=1; 
					b[i][j+1]=1; 
				}
			}
		}
		
		for(int i=1;i<=m;i++){
			a[1][i]=1;
			b[n][i]=1; 
		} 
		
		for(int i=1;i<=m;i=i+2){
			for(int j=1;j<n;j++){
				a[j][i]=1;
			}
		}
		for(int i=2;i<=m;i=i+2){
			for(int j=2;j<=n;j++){
				b[j][i]=1;
			}
		}
	
		
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				printf("%d",a[i][j]);
			}
			printf("\n");
		}
		
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				printf("%d",b[i][j]);
			}
			printf("\n");
		}
	
	
		return 0;
	}
	
	

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

这题题目是真的恶心,好多看不懂的单词还有好多没用的单词...

最后还是开了翻译,幸好队友做了出来了...

一开始我发现前几个样例,发现边数为2n+2,然后又发现了一个样例不符合;然后我感觉是前缀和...其实不是...

n个方块单独放时候的边数为4n,所以我们只需要减去重叠的时候边的数目即可;

我们考虑重力为竖直向下的时候,如果一个方块下面有一个方块,ans需要减去2,如果这个方块左边有相邻的方块ans也需要减2,右边也同理(画个图还是很好想的)

想到这代码应该就很好写了

#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>
using namespace std;
typedef  long  long ll ;
#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');
	}
}
ll ex_gcd(ll a,ll b,ll& x,ll& y){
	if(b==0){
		x=1;
		y=0;
		return a;
	}

	ll d=ex_gcd(b,a%b,y,x);
	y=y-a/b*x;
	return d;
}
int vis1[200005];//行 
int vis2[200005];//列 
int n;
int main(){
	scanf("%d",&n);
	int ans1=0;
	int ans2=0;
	for(int i=1;i<=n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		vis1[x]++;
		vis2[y]++;
		ans1=ans1+4;//向下 
		ans2=ans2+4;//向左 
		if(vis2[y]>1){
			ans1=ans1-2; 
		}
		if(vis2[y-1]>=vis2[y]){
			ans1=ans1-2; 
		}
		if(vis2[y+1]>=vis2[y]){
			ans1=ans1-2;
		}
		
		if(vis1[x]>1){
			ans2=ans2-2; 
		}
		if(vis1[x-1]>=vis1[x]){
			ans2=ans2-2; 
		}
		if(vis1[x+1]>=vis1[x]){
			ans2=ans2-2;
		}
		printf("%d %d\n",ans1,ans2);
		
		
	} 


	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值