【NOIP 2011 提高组 Day1】

#题目
A【NOIP 2011 提高组 Day1】铺地毯
B【NOIP 2011 提高组 Day1】选择客栈
C【NOIP 2011 提高组 Day1】mayan 游戏

 A. 【NOIP 2011 提高组 Day1】铺地毯

每输入一张地毯就判断所求点在不在范围内,在的话就更新答案;

送分题100分到手~

B. 【NOIP 2011 提高组 Day1】选择客栈

这题考试时我打了两个代码,数据量小于10000用暴力,大于10000用自己yy的算法,,

自己yy的算法果然炸了,,,,

考完立马去看数据,把第二个测试点带进去模拟一遍立马就找到了bug,自己的算法思路是没问题的,就是没考虑周全。

话说考试时只有一个样例数据真的坑啊,noip应该有多组样例吧,,,,但愿,,,

暴力60分到手,,我的100啊啊啊,,

附上核心代码

for(int i=1;i<=n;i++){
		int flag=0;
		if(pay[i]<=p)flag=1;
		for(int j=i+1;j<=n;j++){
			if(pay[j]<=p)flag=1;
			if(col[j]==col[i]&&flag){
				ans+=sp[i];
				if(!sp[j])sp[j]=sp[i]+1;
				else sp[j]++;//就是这里把我坑了!!
				sp[i]=0; 
				break;
			}
			if(col[j]==col[i]&&sp[i])sp[j]=sp[i];
		}
		ans+=sp[i];
	}

C. 【NOIP 2011 提高组 Day1】mayan 游戏

看到这题就立马感到不妙,,,,

果然又是那种要考虑贼多情况,代码贼长,让人崩溃的题,,

考试时主要卡在了回溯那里,一直没想到消除之后怎么把它还原。

然后我就看到了

【数据范围】

对于 30%的数据,初始棋盘上的方块都在棋盘的最下面一行

30分我来了!!!!

诶?只有20分,,,

好嘛,原来是只要遇到三个就要消,我还傻乎乎的等它走完规定步数再消,,,,

果然为了改这道题也废了我巨多时间

附上辣鸡代码

 

#include<bits/stdc++.h>
using namespace std;
int n,a[10][10],xx[10],yy[10],did[10];
int used[10][10][10],v[10][10];
bool checkzero(){
	for(int i=1;i<=5;i++)if(a[1][i])return 0;
	return 1;
}
int bang(){
	int f=0;
	for(int j=1;j<=5;j++){
		for(int i=1;i<=7;i++){
			if(a[i][j]){
				if(i>1&&i<7&&a[i][j]==a[i-1][j]&&a[i][j]==a[i+1][j]){
					v[i][j]=v[i-1][j]=v[i+1][j]=1;
					if(i>=3&&a[i-2][j]==a[i][j])v[i-2][j]=1;
					if(i<=5&&a[i+2][j]==a[i][j])v[i+2][j]=1;
					f=1;
				}
				if(j>1&&j<5&&a[i][j-1]==a[i][j]&&a[i][j+1]==a[i][j]){
					v[i][j]=v[i][j-1]=v[i][j+1]=1;
					if(j>=3&&a[i][j-2]==a[i][j])v[i][j-2]=1;
					if(j<=3&&a[i][j+2]==a[i][j])v[i][j+2]=1;
					f=1;
				}
			}
		}
	}
	if(!f)return 0;
	for(int i=1;i<=7;i++){
		for(int j=1;j<=5;j++)if(v[i][j])a[i][j]=0,v[i][j]=0;
	}
	return 1;
}
void down(){
	for(int j=1;j<=5;j++){
		int d=0;
		for(int i=1;i<=7;i++){
			if(!a[i][j])d++;
			if(a[i][j]&&d){a[i-d][j]=a[i][j];a[i][j]=0;
			}
		}
	}
}
void copy(int x){
	for(int i=1;i<=7;i++){
		for(int j=1;j<=5;j++)used[x][i][j]=a[i][j];
	}
}
void bling(int x){
	for(int i=1;i<=7;i++){
		for(int j=1;j<=5;j++)a[i][j]=used[x][i][j];
	}
}
void dfs(int cnt){
//	cout<<cnt<<":"<<endl;
//	for(int i=7;i>=1;i--){for(int j=1;j<=5;j++)cout<<a[i][j]<<" ";cout<<endl;
//	}
	down();
	while(bang())down();
	if(cnt==n+1&&checkzero()){
		for(int i=1;i<n;i++)printf("%d %d %d\n",xx[i]-1,yy[i]-1,did[i]);
		printf("%d %d %d",xx[n]-1,yy[n]-1,did[n]);
		exit(0);
	}
	if(cnt>n)return;
	copy(cnt);
	for(int j=1;j<=5;j++){
		for(int i=1;i<=7;i++){
			if(a[i][j]&&a[i][j]!=a[i][j+1]){
				if(j<5){
			swap(a[i][j],a[i][j+1]);
			xx[cnt]=j,yy[cnt]=i,did[cnt]=1;
			dfs(cnt+1);
			bling(cnt);
		}
				if(j>1&&!a[i][j-1]){
			swap(a[i][j],a[i][j-1]);
			xx[cnt]=j,yy[cnt]=i,did[cnt]=-1;
			dfs(cnt+1);
			bling(cnt);
		}
		}
		}
		
	}
}
int main(){
//	freopen("mayan.in","r",stdin);
//	freopen("mayan.out","w",stdout);
	scanf("%d",&n);
	for(int j=1;j<=5;j++){
		int x,t=0;
		while(cin>>x&&x)a[++t][j]=x;
	}
//for(int i=7;i>=1;i--)for(int j=1;j<=5;j++)cin>>a[i][j];
//n=1;
	dfs(1);
	printf("-1");
	return 0;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值