NOIP2008普及组

T2】排座椅

 横行相同时列数+1,纵行相同时行数+1。

主要是用桶排序,因为范围太大了,用sort会超时

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<set>
using namespace std;
const int maxn=1010;
const int INF=0x3fffffff;
int m,n,k,l,d;
int xi,xj,yi,yj;
int heng[1001],shu[1001];
int h[1001],s[1001];
int main(){
	scanf("%d %d %d %d %d",&m,&n,&k,&l,&d);   //这题数据量大,用cin肯定会超时的 
	int maxheng=0,maxshu=0;
	for(int i=1;i<=d;i++){
		scanf("%d %d %d %d",&xi,&xj,&yi,&yj);
		if(xi==yi) {
			int t=min(xj,yj);
			if(t>maxshu) maxshu=t;
			shu[t]++;
		}
		else if(xj==yj) {
			int t=min(xi,yi);
			if(t>maxheng) maxheng=t;
			heng[t]++;
	}
}
	for(int i=1;i<=k;i++){   //桶排序 ,用sort很费时 
		int maxs=-1,d;
		for(int j=1;j<m;j++){
			if(maxs<heng[j]){
				maxs=heng[j];
				d=j;
			}
		}
		heng[d]=0;
		h[d]++;
	}
	for(int i=1;i<=l;i++){
		int maxs=-1,d;
		for(int j=1;j<n;j++){
			if(maxs<shu[j]){
				maxs=shu[j];
				d=j;
			}
		}
		shu[d]=0;
		s[d]++;
	}
	
//我的四次排序:超时了 呵呵 
/*
	sort(heng,heng+maxheng+1,cmp);
	sort(shu,shu+maxshu+1,cmp);
	sort(heng,heng+k,cmp2);
	sort(shu,shu+l,cmp2);
	*/
	for(int i=1;i<=maxheng;i++){
		if(h[i]) printf("%d ",i);
	}
	cout<<endl;
	for(int i=1;i<=maxshu;i++){
		if(s[i]) printf("%d ",i);
	}
return 0;
}

  

T3】传球游戏

 

感觉像是数学题

。。。但是并不是

  1. //知道是简单的DP
  2. //f[i][j]表示第i次传到第j个人手里的方法总数
  3. //f[i][j] = f[i-1][j-1]+f[i-1][j+1];(还要对环做一下处理)
  4. //边界:f[0][1] = 1;
  5. //解:f[m][1]
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<set>
using namespace std;
const int maxn=1010;
const int INF=0x3fffffff;
//知道是简单的DP
//f[i][j]表示第i次传到第j个人手里的方法总数
//f[i][j] = f[i-1][j-1]+f[i-1][j+1];(还要对环做一下处理)
//边界:f[0][1] = 1;
//解:f[m][1]; 
int a[maxn][maxn];
int n,m; 
int main(){
	cin>>n>>m;
	int l,r;
	a[0][1]=1;
	for(int i=1;i<=m;i++){ //传m次 
		for(int j=1;j<=n;j++){
			if(j==1) l=n;
			else l=j-1;
			if(j==n) r=1;
			else r=j+1;
			a[i][j]=a[i-1][l]+a[i-1][r];
		} 
	}
	cout<<a[m][1]<<endl;
return 0;
}

  

T4】立体图

 

 怕了怕了

看起来就好复杂

就是模拟

1 算出画布的长宽L、K

L = 4n+1+2m

k = max(3*h[i][j]+1+2*(m-i+1));

 2 立方体(i, j)的左下角在画布上的坐标(x, y)

x = k - 2*(m-i)

y = 4*(j-1)+2*(m-i)+1;

 3 写出Draw(i, j)函数 以画布i,j为左下角画一个方格

#include <iostream>
using namespace std;
 
int m, n, k, l;
int h[101][101];
char canvax[1001][1001];
char block[6][8]={
	"..+---+",
	"./   /|",
	"+---+ |",
	"|   | +",
	"|   |/.",
	"+---+..",
};
void draw(int x,int y){
	for(int i=0;i<6;i++){
		for(int j=0;j<7;j++){ //x,y是左下角 
			if(block[i][j]!='.') canvax[x-5+i][y+j]=block[i][j];
		}
	}
}
int main(){
	cin>>m>>n;
	l=4*n+1+2*m;
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			cin>>h[i][j];
			k=max(k,3*h[i][j]+1+2*(m-i+1));
		}
	}
	for(int i=1;i<=k;i++){
		for(int j=1;j<=l;j++) canvax[i][j]='.';
	}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			int x,y;
			x=k-2*(m-i);
			y=4*(j-1)+2*(m-i)+1;
			while(h[i][j]>0){
				h[i][j]--;
				draw(x,y);
				x-=3;
			}
		}
	}
	for(int i=1;i<=k;i++,cout<<endl){
		for(int j=1;j<=l;j++)cout<<canvax[i][j];
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/shirlybaby/p/13633944.html