2010-2011 ACM-ICPC, NEERC, Southern Subregional Contest

A

(坑)

B

水题,XJB搞搞就过了啊?

#include<bits/stdc++.h>
using namespace std;
const int MAXN=105;
typedef long long ll;
int mp[MAXN][MAXN];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	int n,m;
	scanf("%d %d\n",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			char tmp;
			scanf("%c",&tmp);
			mp[i][j]=tmp-'0';
		}
		getchar();
	}
	ll ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			for(int k=0;k<4;k++)
			{
				int tx,ty;
				tx=i+dir[k][0];
				ty=j+dir[k][1];
				ans+=max(0,mp[i][j]-mp[tx][ty]);
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(!mp[i][j])
			{
				ans-=2;
			}
		}
	}
	printf("%lld\n",ans+m*n*2);
	return 0;
}

C

爆搜+剪枝。。。还是要学习一个先进的剪枝技术啊。。。

#include<bits/stdc++.h>
using namespace std;
char u[30][30];
int dp[33554432];
int in[30];
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
	int N, M, i, j;
	scanf("%d %d", &N, &M);
	for (i = 0; i < N; i++) {
		scanf("%s", u[i]);
		for (j = 0; j < M; j++) if (u[i][j] == '*') in[i] |= 1 << j;
	}

	int ans = 0;
	dp[(1 << N) - 1] = 0;
	ans = __builtin_popcount((1 << N) - 1);

	for (i = (1 << N) - 2; i >= 0; i--) {
		int t = __builtin_ctz(~i);
		dp[i] = dp[i | (1 << t)] | in[t];
		ans = min(ans, max(__builtin_popcount(i), __builtin_popcount(dp[i])));
	}
	return !printf("%d\n", ans);
}

D

貌似有向图博弈啊?不是我写的/摊手

#include <iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<cmath>

using namespace std;

struct node{
	vector<int>con;
	int lay;
	int win;
	int vis;
}nodes[1005];

void dfs(int x)
{
    int siz = nodes[x].con.size();
    for(int i = 0 ;i<siz;i++)
    {
        int next = nodes[x].con[i];
        if(nodes[next].lay==nodes[x].lay+1)
        {
            if(nodes[next].vis==0)
            {
                dfs(next);
            }
            if(nodes[next].win==0)
            {
                nodes[x].win = 1;
            }
        }
    }
    return;
}

int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	int n, m;
	cin >> n >> m;
	int be, ed;
	for (int i = 0; i<m; i++)
	{
		cin >> be >> ed;
		nodes[be].con.push_back(ed);
		nodes[ed].con.push_back(be);
	}

	queue<int>que;

	que.push(1);
	nodes[1].lay = 1;

	while(!que.empty())
    {
        int now = que.front();
        que.pop();
        int siz = nodes[now].con.size();
        for(int i =0;i<siz;i++)
        {
            int next = nodes[now].con[i];
            if(nodes[next].lay==0)
            {
                nodes[next].lay = nodes[now].lay+1;
                que.push(next);
            }
        }
    }

    dfs(1);

	if (nodes[1].win)
	{
		cout << "Vladimir\n";
	}
	else
	{
		cout << "Nikolay\n";
	}
	return 0;
}

E

bfs搜一搜就好了,水题

#include<bits/stdc++.h>
using namespace std;
const int MAXN=205;
int mp[MAXN][MAXN];
int a[MAXN];
vector<int> ans,cnt;
struct node
{
	int now,at;
	node(){}
	node(int _now,int _at):now(_now),at(_at){}
};
int n,k;
bool book[MAXN][MAXN];
void bfs(int now)
{
	memset(book,false,sizeof(book));
	queue<node> Q;
	book[now][1]=true;
	Q.push(node(now,1));
	while(!Q.empty())
	{
		node top=Q.front();
		Q.pop();
		int id=top.at;
		now=top.now;
		if(id==k+1)
		{
			ans.push_back(now);
			continue;
		}
		for(int i=1;i<=n;i++)
		{
			if(mp[now][i]==a[id])
			{
				if(!book[i][id+1])
				{
					book[i][id+1]=true;
					Q.push(node(i,id+1));
				}	
			}
		}
	}
}
int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&mp[i][j]);
		}
	}
	scanf("%d",&k);
	for(int i=1;i<=k;i++)
	{
		scanf("%d",&a[i]);
	}
	bfs(1);
	sort(ans.begin(),ans.end());
	for(int i=0;i<ans.size();i++)
	{
		if(i-1<0||ans[i]!=ans[i-1])
		{
			cnt.push_back(ans[i]);
		}
	}
	printf("%d\n",cnt.size());
	for(int i=0;i<cnt.size();i++)
	{
		printf("%d%c",cnt[i],(i==cnt.size()-1?'\n':' '));
	}
	return 0;
}

F

模拟,水题

#include<bits/stdc++.h>
using namespace std;
const int MAXN=105;
bool dp[MAXN];
int a[MAXN];
vector<int> ans;
int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		dp[a[i]]=true;
	}
	int now=m;
	for(int i=1;i<=n;i++)
	{
		if(!dp[a[i]])
			continue;
		if(now>a[i])
		{
			for(int j=now;j>=a[i];j--)
			{
				if(dp[j])
				{
					ans.push_back(j);
					dp[j]=false;
				}
			}
		}
		else
		{
			for(int j=now;j<=a[i];j++)
			{
				if(dp[j])
				{
					ans.push_back(j);
					dp[j]=false;
				}
			}
		}
	}
	for(int i=0;i<ans.size();i++)
	{
		printf("%d%c",ans[i],(i==ans.size()-1?'\n':' '));
	}
	return 0;
}

G

dfs能搜过去啊?处理出点i能到的所有的点O(n^2),然后枚举边然后计算形成的联通块大小O(n*m),就暴力过了啊?

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
using namespace std;
const int MAXN=1010;
vector<pair<int,int> > sv;
bool MP[MAXN][MAXN],G[MAXN][MAXN];
bool book[MAXN];
int n,m;
void dfs(int now,int root)
{
	book[now]=true;
	for(int i=1;i<=n;i++)
	{
		if(!book[i]&&MP[now][i])
		{
			G[root][i]=1;
			dfs(i,root);
		}
	}
}
vector<int> ans[MAXN];
int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		MP[u][v]=1;
		sv.push_back(mp(u,v));
	}
	if(m==0)
		return 0*printf("1\n0\n");
	int mx=0;
	for(int i=1;i<=n;i++)
	{
		memset(book,false,sizeof(book));
		dfs(i,i);
		G[i][i]=1;
	}
	for(int i=0;i<m;i++)
	{
		int u=sv[i].xx,v=sv[i].yy;
		int cnt=0;
		for(int j=1;j<=n;j++)
		{
			if(G[u][j]&&G[j][v])
				cnt++;
		}
		mx=max(cnt,mx);
		ans[cnt].push_back(i+1);
	}
	printf("%d\n",mx);
	printf("%d\n",ans[mx].size());
	sort(ans[mx].begin(),ans[mx].end());
	printf("%d",ans[mx][0]);
	for(int i=1;i<ans[mx].size();i++)
	{
		printf(" %d",ans[mx][i]);
	}
	printf("\n");
	return 0;
}

H

神奇的排序加最长上升子序列的题目(不是我写的啊,我好菜啊?)

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int up[MAXN];
int n;
struct node
{
	int x,y,id,t;
	bool operator <(const node &a)const
	{
		if(x==a.x)
			return y>a.y;
		return x<a.x;
	}
	node(){}
	node(int _x,int _y,int _id):x(_x),y(_y),id(_id){}
}po[MAXN];
vector<node> sv[MAXN];
vector<int> A,B;
int pocnt[MAXN],posmax[MAXN];
int pos[MAXN];
int main()
{
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	scanf("%d",&n);
	memset(up,0x3f,sizeof(up));
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&po[i].x,&po[i].y);
		po[i].id=i;
	}
	sort(po+1,po+1+n);
	int mx=0;
	for(int i=1;i<=n;i++)
	{
		int y=po[i].y;
		po[i].t = i;
		int Pos=lower_bound(up+1,up+MAXN,y)-up;
		up[Pos]=y;
		mx=max(mx,Pos);
		sv[Pos].push_back(po[i]);
		pos[i]=Pos;
	}
	int la=0x3f3f3f3f;
	//printf("%d\n");
	int mi=mx;
	/*for(int i = 1;i <= n;i++)
		printf("%d ",pos[i]);
	printf("\n");*/
	memset(pocnt,0,sizeof(pocnt));
	posmax[mx+1] = 1e9;
	for(int i=n;i>=1;i--)
	{
		if(pos[i]==mi){
			mi--;	
		}
		if(pos[i]<mi||po[i].y >= posmax[pos[i]+1])
			pos[i] = -1;
		if(pos[i] >= 0){
			posmax[pos[i]] = po[i].y;
			B.push_back(po[i].id);
			pocnt[pos[i]]++;
			}
	}
	for(int i=n;i>=1;i--)
		if(pos[i]>=0)
			if(pocnt[pos[i]]==1)
				A.push_back(po[i].id);
	/*for(int i=mx;i>=1;i--)
	{
		int sz=sv[i].size();
		int cnt=0,T;
		for(int j=0;j<sz;j++)
		{
			int y=sv[i][j].y;
			int id=sv[i][j].id;
			if(y>=la)
			{
				continue;
			}
			if(pos[sv[i][j].t]>=0)
			{
				cnt++;
				T=id;
				B.push_back(id);
			}
		}
		if(cnt==1)
			A.push_back(T);
		for(int j=0;j<sz;j++)
			if(sv[i][j].y< la&&pos[sv[i][j].t]>=0){
				la=sv[i][j].y;
				break;
			}
	}*/
	sort(A.begin(),A.end());
	sort(B.begin(),B.end());
	printf("%d",B.size());
	for(int i=0;i<B.size();i++)
	{
		printf(" %d",B[i]);
	}
	printf("\n");
	printf("%d",A.size());
	for(int i=0;i<A.size();i++)
	{
		printf(" %d",A[i]);
	}
	printf("\n");
	return 0;
}

I

(坑)

J

固定一个点,然后三分,复杂度O(n*n*log20000)

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int n;
const double eps = 1e-10;
double ans[500],a[500],b[500];
double cnt(double d,int x){
	for(int i = 1;i <= n;i++)
		b[i] = a[x] + (i-x)*d;
	double ret = 0;
	for(int i = 1;i <= n;i++)
		ret += fabs(a[i]-b[i]);
	return ret; 
}
double tsearch(double l,double r,int x){
	if(r-l<eps)
		return l;
	double m1 = (r-l)/3.0+l;
	double m2 = (r-l)/3.0*2.0+l;
	double an1 = cnt(m1,x),an2 = cnt(m2,x);
	if(an1<an2)
		return tsearch(l,m2,x);
	else
		return tsearch(m1,r,x);
}
int main(){
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	scanf("%d",&n);
	for(int i = 1;i <= n;i++)
		scanf("%lf",&a[i]);
	double x;
	for(int i = 1;i <= n;i++){
		ans[i] = tsearch(0.0,10000.0,i);
	}
	double res = 1e9;
	for(int i = 1;i <= n;i++)
		res = min(res,cnt(ans[i],i));
	for(int i = 1;i <= n;i++)
		if(fabs(res-cnt(ans[i],i))<eps){
			printf("%lf\n",res);
			for(int i = 1;i < n;i++)
				printf("%.10lf ",b[i]);
			printf("%.10lf\n",b[n]);
			break;
	} 
} 

K

(坑)

L

(坑)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值