10.11NOIP模拟赛

问题 A: 图腾计数

时间限制: 1 Sec
内存限制: 128 MB
提交: 95
解决: 54

题目描述

      whitecloth 最近参观了楼兰图腾。图腾的所在地有一排N 个柱子,N个柱子的高度恰好为一个1 到N 的排列,而楼兰图腾就隐藏在这些柱子中。由于whitecloth 弱爆了,他只知道图腾由3 个柱子组成,这三个柱子组成了下凸或上凸的图形(>.<),所谓下凸,设三个柱子的高度从左到右依次为h1,h2,h3,那么h1>h2,h3>h2,上凸则满足h1<h2,h3<h2。现在whitecloth 也找不到图腾具体是哪三个柱子,他只想知道满足这两个形状的柱子有几组。

输入

第一行一个数N
接下来一行N 个数,依次表示每个柱子的高度

输出

一行两个数,表示下凸形状的数量和上凸形状的数量,用空格隔开

样例输入

51 5 3 2 4

样例输出

3 4

提示

对于30%的数据,N<=100

对于100%的数据,N<=200000



问题 B: 分糖果

时间限制: 1 Sec
内存限制: 128 MB
提交: 88
解决: 33

题目描述

       whitecloth 有N 个糖果,小猫rainbow 和freda 来找whitecloth 要糖吃……对于每个糖果,rainbow 和freda 各有一个喜欢度ri 和fi,whitecloth不能不给他们糖果(他们会闹的),但又不想全给,于是whitecloth决定给他们恰好M 块糖果。为了让两只小猫不要闹矛盾,whitecloth 希望所给糖果的ri 的和与fi的和的差值的绝对值尽量小,在此基础上,whitecloth 还希望所有ri和fi 的总和最大,于是他请你来帮他出主意。

输入

第一行两个数N,M
接下来N 行,每行两个数ri,fi

输出

第一行一个数,表示最小的差值的绝对值
第二行一个数,表示最大的ri 和fi 的总和。

样例输入

4 21 22 34 16 2

样例输出

210

提示

对于30%的数据,N<=20,M<=10


对于100%的数据,N<=200,M<=20,1<=ri,fi<=20,M<=N







注意数组下标为负如何处理

问题 C: 智力游戏

时间限制: 1 Sec
内存限制: 128 MB
提交: 71
解决: 29

题目描述

       whitecloth 最近迷上了一个你小时候已经玩厌了的游戏:移火柴棒。他现在吵着要你陪他玩,你没有办法,只好写一个程序来完成这个工作了。

你被给出了一个火柴拼成的等式,比如说下面这个:( 5 + 7 = 7 )

它显然是不成立的,但是我们可以通过移动一个其中的火柴使得它成立。变成如下的一个等式:( 6 + 1 = 7 )

现在给出一个类似的等式,请问最少移动多少根火柴可以使得它变成一个成立的等式。

输入

三个整数,表示原等式中的两个加数以及和

输出

一个数,表示最小移动几根火柴能使等式成立,不允许改变位数以及符号,不要制造0 开头的数。

样例输入

5 7 7

样例输出

1

提示

对于100%的数据,每个数在0 到999 之间

问题 D: 最远距离

时间限制: 1 Sec
内存限制: 128 MB
提交: 87
解决: 33

题目描述

      whitecloth 有一块矩形土地,被分为N*M 块1*1 的小格子。有的格子含有障碍物。如果从格子A 可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离。如果从格子A 不可以走到格子B,就没有距离。如果格子X 和格子Y 有公共边,并且X 和Y 均不含有障碍物,就可以从X 走到Y。如果whitecloth 可以移走T 块障碍物,求所有格子间的最大距离。保证移走T 块障碍物以后,至少有一个格子不含有障碍物。

输入

第一行包含三个整数,N M T。
接下来有N 行,每行一个长度为M 的字符串,'0'表示空格子,'1'表示该格子含有障碍物。

输出

一个数表示答案,保留6 位小数

样例输入

3 3 0001001110

样例输出

1.414214

提示

对于20%的数据,满足1 <= N,M <= 30 ,0 <= T <= 0

对于40%的数据,满足1 <= N,M <= 30 ,0 <= T <= 2

对于100%的数据,满足1 <= N,M <= 30 ,0 <= T <= 30

//下凸 h1>h2<h3
//上凸 h1<h2>h3
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
typedef long long LL;
const int MAXN=200010;

int n;
LL shangtu,xiatu;
int qianda[MAXN],houda[MAXN];
int qianxiao[MAXN],houxiao[MAXN];
int a[MAXN],t[MAXN],b[MAXN],c[MAXN],d[MAXN];

void add(int x,int d) {
	while(x<=n) {
		t[x]+=d;
		x+=(x&(-x));
	}
}

int sum(int x) {
	int res=0;
	while(x) {
		res+=t[x];
		x-=(x&(-x));
	}
	return res;
}

void work2() {
	int i,j;
	for(i=1;i<=n;++i) scanf("%d",&a[i]);
	for(i=1;i<=n;++i) {
		add(a[i]+1,1);
		c[i]=sum(a[i]);
	}
	memset(t,0,sizeof(t));
	for(i=n;i>=1;i--) {
		add(a[i]+1,1);
		d[i]=sum(a[i]);
	}
	for(i=1;i<=n;++i) {
		shangtu+=(LL)c[i]*d[i];
		xiatu+=(LL)(i-1-c[i])*(n-i-d[i]); 
	}
	printf("%lld %lld",xiatu,shangtu);
}

void init() {
	int i;
	scanf("%d",&n);
	work2();
}

int main() {
	init();
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int MAXN=205;

int f[MAXN][1510],Max,n,m;
int l[MAXN],r[MAXN];
bool p[MAXN][1510];

void init() {
	int i,j,k;
	scanf("%d%d",&n,&m);
	for(i=1; i<=n; ++i) scanf("%d%d",&l[i],&r[i]);
	f[0][1000]=0;p[0][1000]=1;
	for(k=1; k<=n; ++k)
		for(i=m; i; --i)
			for(j=500; j<=1500; j++)
				if(p[i-1][j-l[k]+r[k]]&&f[i][j]<f[i-1][j-l[k]+r[k]]+l[k]+r[k]) {
					f[i][j]=f[i-1][j-l[k]+r[k]]+l[k]+r[k];
					p[i][j]=1;
				}
	int ans1=0x3f3f3f3f,ans2=-1;
	for(i=0;i<=500;++i) {
		if(p[m][i+1000]||p[m][1000-i]) {
			ans1=i;
			break;
		}
	}
	if(p[m][ans1+1000]&&ans2<f[m][ans1+1000]) ans2=f[m][ans1+1000];
	if(p[m][1000-ans1]&&ans2<f[m][1000-ans1]) ans2=f[m][1000-ans1];
	printf("%d\n%d",ans1,ans2);
}


int main() {
	init();
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int MAXN=1010;

int a,b,c,tot,ans=0x3fffffff;
int huo[10]={6,2,5,5,4,5,6,3,7,6};
bool at[10][7];

int sum(int x) {
	int res=0;
	if(x<10) return huo[x];
	else  {
		while(x){
			int temp=x%10;
			res+=huo[temp];
			x/=10;
		}
	}
	return res;
}

void change(int x,int *arr) {
	if(!x) {
		arr[++arr[0]]=0;
		return;
	}
	while(x) {
		arr[++arr[0]]=x%10;
		x/=10;
	}
}

int Min(int a,int b) {
	return a<b?a:b;
}

int make(int a,int b,int c,int A,int B,int C) {//A->a B->b C->c
	int x[5]={0},y[5]={0},z[5]={0},X[5]={0},Y[5]={0},Z[5]={0},res=0,i,j;
	change(a,x),change(b,y),change(c,z),change(A,X),change(B,Y),change(C,Z);
	if(x[0]!=X[0]||y[0]!=Y[0]||z[0]!=Z[0]) return 0x3fffffff;
	for(i=1;i<=x[0];++i) {
		int aa=x[i],AA=X[i];
		for(j=0;j<7;++j)
		    if((at[aa][j]==1&&at[AA][j]==0))
		        res++;
	}
	for(i=1;i<=y[0];++i) {
		int bb=y[i],BB=Y[i];
		for(j=0;j<7;++j)
		    if((at[bb][j]==1&&at[BB][j]==0))
		        res++;
	}
	for(i=1;i<=z[0];++i) {
		int cc=z[i],CC=Z[i];
		for(j=0;j<7;++j)
		    if((at[cc][j]==1&&at[CC][j]==0))
		        res++;
	}
	return res;
}

void work() {
	int i,j;
	for(i=0;i<=1000;++i)
	    for(j=0;j<=1000;++j) {
			if(i+j<=1000&&sum(i)+sum(j)+sum(i+j)==tot) {
				int temp=make(a,b,c,i,j,i+j);
				ans=Min(ans,temp);
			}
	    }
	printf("%d",ans);
}

void init(){
	at[0][0]=1;at[0][1]=1;at[0][2]=1;at[0][3]=1;at[0][4]=1;at[0][6]=1;
	at[1][2]=1;at[1][4]=1;
	at[2][0]=1;at[2][2]=1;at[2][3]=1;at[2][5]=1;at[2][6]=1;
	at[3][0]=1;at[3][2]=1;at[3][4]=1;at[3][5]=1;at[3][6]=1;
	at[4][1]=1;at[4][2]=1;at[4][4]=1;at[4][5]=1;
    at[5][0]=1;at[5][1]=1;at[5][4]=1;at[5][5]=1;at[5][6]=1;
    at[6][0]=1;at[6][1]=1;at[6][3]=1;at[6][4]=1;at[6][5]=1;at[6][6]=1;
    at[7][0]=1;at[7][2]=1;at[7][4]=1;
    at[8][0]=1;at[8][1]=1;at[8][2]=1;at[8][3]=1;at[8][4]=1;at[8][5]=1;at[8][6]=1;
    at[9][0]=1;at[9][1]=1;at[9][2]=1;at[9][4]=1;at[9][5]=1;at[9][6]=1;
	scanf("%d%d%d",&a,&b,&c);
	if(a+b==c){
		printf("0");
		return ;
	}
	tot=sum(a)+sum(b)+sum(c);
//	printf("tot=%d\n",tot);
	work();
}

int main(){
	init();
	while(1);
}

# include <iostream>
# include <cstdio>
# include <algorithm>
# include <cstring>
# include <deque>
# include <cmath>

# define Max(a,b) ((a)>(b)?(a):(b))

using namespace std;

const int MAXN=40;

int n,m,T;
int gx[4]={1,0,-1,0};
int gy[4]={0,1,0,-1};
double ans;
bool map[MAXN][MAXN];

void bfs(int x,int y) {
	double qx,qy;
	deque < pair<int,int> > q;
	bool vis[MAXN][MAXN];
	int dis[MAXN][MAXN];
	memset(vis,0,sizeof(vis));
	dis[x][y]=map[x][y];
	vis[x][y]=1;
	q.push_back(make_pair(x,y));
	while(!q.empty()) {
		pair<int,int> t=q.front();
		q.pop_front();
		int cost=dis[t.first][t.second];
		int xx,yy;
		if(cost>T) break;
		qx=(double)t.first-x;
		qy=(double)t.second-y;
		ans=Max(qx*qx+qy*qy,ans);
		for(int d=0; d<4; ++d) {
			xx=t.first+gx[d];
			yy=t.second+gy[d];
			if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]) {
				if(map[xx][yy]) {
					q.push_back(make_pair(xx,yy));
					dis[xx][yy]=cost+1;
				} else {
					q.push_front(make_pair(xx,yy));
					dis[xx][yy]=cost;
				}
				vis[xx][yy]=1;
			}
		}
	}
	return ;
}

void init() {
	int i,j;
	char x;
	cin>>n>>m>>T;
	for(i=0; i<n; ++i)
		for(j=0; j<m; ++j) {
			cin>>x;
			map[i][j]=x=='1';
		}
	for(i=0; i<n; ++i)
		for(j=0; j<m; ++j)
			bfs(i,j);
	ans=sqrt(ans);
	printf("%.6lf",ans);
	return ;
}

int main() {
	freopen("distance.in","r",stdin);
	freopen("distance.out","w",stdout);
	init();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值