ACdream原创群赛(14)の我今天没吃药

由于 期末考试 代码敲得少了 (借口? 是的!!) 什么状态也没有, 一个 简单题目也能出各种奇葩 错误, 最近的各种比赛各种不顺畅, 很是不爽!!

我在瓶颈了? 思维 和 代码能力 都要提升!!不过多的 发出弱者的牢骚了T_T

题目LINK: Click here

本文来自: http://blog.csdn.net/napoleon_acm/article/details/37502255

A - 瑶瑶的第K大

给你n个数(5e6大小), 每组数据一个询问, 这N个数第k大的是哪个。

排序 O(n log n)肯定会超时, 可以 用快排 修改一下, 递归去找, 之后输入很多还要用到输入外挂才能过.

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define INF 1000000000
//typedef __int64 LL;
#define N 5000006

int num[N], n, k;
inline void scanf_(int &num)
{
	char in ;
	while((in=getchar())>'9' || in<'0');
	num=in-'0';
	while(in=getchar(), in>='0' && in<='9')
		num *= 10, num+= in-'0';
}
int sol(int L , int R, int k )
{
	if(L==R) return num[L];
 	int now=num[L];
 	int l, r;
 	l=L; r=R;
 	while(l < r)
 	{
 		while(l<r && num[r]<=now) r--;
 		num[l]=num[r];
 		while(l<r && num[l]>=now) l++;
 		num[r]=num[l];
 	}
 	num[l]=now;
 	if(l-L+1 ==k) return num[l];
 	else if(l-L >= k) return sol(L, l , k);
 	else return sol(l+1, R, k - (l-L+1));
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
	while(scanf("%d%d", &n, &k)!=EOF)
	{
		for(int i=1; i<=n; i++) scanf_(num[i]);  //scanf("%d", &num[i]);
		printf("%d\n", sol(1, n, k));
	}

	return 0;
}

B - 瑶瑶饿了

n个点, 每个点有一种食物 , 给出有多少份,每吃一份的耗时, 每吃一份获得的能量。 n个点构成一张有向图,到每个点的最短时间算入总时间,求T时间内能获得的最多能量。

先用Floyd处理出来最短路(spfa也可以), 之后相当于一个简单依赖背包, 可以用分组背包来解。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define INF 1000000000
typedef long long LL;
#define N 110
LL n,m,t, mm[N][N];
LL w[N], c[N], sum[N], dp[1005];
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
	while(scanf("%lld%lld%lld", &n, &m, &t)!=EOF)
	{
		for(int i=1; i<=n; i++)
		{
			scanf("%lld%lld%lld", &sum[i], &w[i], &c[i]);
		}
		for(int i=0; i<=n; i++)
			for(int j=0; j<=n ;j++)
				if(i==j) mm[i][i]=0;
				else  mm[i][j]=INF;
		LL u,v,g;
		for(int i=1; i<=m; i++)
		{
			scanf("%lld%lld%lld", &u, &v, &g);
			mm[u][v]= min (mm[u][v], g);
		}
		// floyd
		for(int k=0; k<=n; k++)
			for(int i=0; i<=n; i++)
				for(int j=0; j<=n; j++)
					if(mm[i][k] + mm[k][j] < mm[i][j]) mm[i][j]= mm[i][k] + mm[k][j];
		memset(dp, 0, sizeof(dp));
		for(int i=1; i<=n ;i++)
		{
			for(int j=t; j>=0; j--)
			{
				for(int k=1; k<=sum[i]; k++)
				{
					if(j+ mm[0][i] + k*c[i] > t) break;
					dp[j+ mm[0][i] + k*c[i]]= max(dp[j+ mm[0][i] + k*c[i]], dp[j] +k*w[i]);
				}
			}
		}
		printf("%lld\n", dp[t]);

	}
	return 0;
}

G - 瑶瑶带你玩激光坦克

这是一个模拟题, 1e6 直接DFS回暴栈, 所以可以直接慢慢搞, 题目讨论区明明说T这个点有且仅有一个,为什么我必须特判没有的情况才能过???(DEBUG半天!)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define INF 1000000000
//typedef __int64 LL;
#define N 1010
int n,m, vis[N][N][6], vv[N][N], ans;
char  mm[N][N];
struct node
{
	int x, y;
};
node get_next(int x,int y,int di)
{
	node ret;
	if(di==0) x--;
	else if(di==1) x++;
	else if(di==2) y--;
	else if(di==3) y++;
	ret.x=x; ret.y=y;
	return ret;
}
int get_dir(int di, char c)
{
	if(c=='/')
	{
		if(di==0) return 3;
		if(di==1) return 2;
		if(di==2) return 1;
		if(di==3) return 0;
	}
	else
	{
		if(di==0) return 2;
		if(di==1) return 3;
		if(di==2) return 0;
		if(di==3) return 1;
	}
}
int test(int x,int y, int di)
{
	if(x<1 || x>n || y<1 || y>m) return -1; // chu jie
	if(mm[x][y]=='*') return 0; // **
	if(vis[x][y][di]) return -2; // have visited this point in this direction
	return 1;
}
void sol(int x, int y, int di)
{
	node now;
	now.x=x; now.y=y;
	while(1)
	{
		now=get_next(now.x, now.y, di);
		int tmp=test(now.x, now.y, di);
		if(tmp<=0) break;
		vis[now.x][now.y][di]=1; // mark the in direction
		if(mm[now.x][now.y]=='E')
		{
			if(!vv[now.x][now.y])
			{
				ans++; vv[now.x][now.y]=1;
			}
		}
		else if(mm[now.x][now.y]=='/')
			di=get_dir(di,'/');
		else if(mm[now.x][now.y]=='\\')
			di=get_dir(di,'\\');
	}
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
	while(scanf("%d%d", &n, &m)!=EOF)//scanf("%d%d", &n, &m);  //
	{
		node S;
		int flag=1;
		for(int i=1; i<=n; i++)
		{
			scanf("%s", mm[i]+1);
			for(int j=1; j<=m; j++)
				if(mm[i][j]=='T')
				{
					S.x=i; S.y=j;mm[i][j]='.', flag=0;
				}
		}
		if(flag)//用特判 'T'是否存在? 讨论区 的回复明明说的是有且仅有一个'T'啊!!!害我调试半天
		{
			printf("0\n"); continue;
		}
		int out=0;
		for(int i=0; i<4; i++)
		{
			ans=0;
			memset(vv, 0, sizeof(vv));
			memset(vis, 0, sizeof(vis));
			vis[S.x][S.y][i]=1;
			sol(S.x, S.y, i);
			out=max(out, ans);
		}
		printf("%d\n", out);
	}
	return 0;
}


H - 游泳水平有限的瑶瑶

给定两个凸多边形(保证没有重叠), 求 两个多边形的最小距离。

可以暴力直接算 两个多边形的边(线段)之间的距离,求最小值 就可以了, 注意两个向量的点乘积的正负可以判断角度是钝角还是锐角, 叉乘可以得出两个向量构成平行四边形的面积, 可以用来求三角形另一边的高。 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define INF 1000000000
//typedef __int64 LL;
#define N 1005
#define eps 0.0000001
int n,m;
struct node
{
	double x, y;
}nod1[N], nod2[N];
double dis(node a, node b)
{
	return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double mul(node a, node b)
{
	return a.x*b.x + a.y*b.y;
}
double Xmul(node a, node b)
{
	return a.x*b.y - a.y * b.x;
}
int dcmp(double in)
{
	if(fabs(in) <= eps) return 0;
	return in>0? 1: -1;
}
node jian(node a, node b)
{
	node ret;
	ret.x = a.x - b.x;
	ret.y = a.y - b.y;
	return ret;
}
node jia(node a, node b)
{
	node ret;
	ret.x = a.x + b.x;
	ret.y = a.y + b.y;
	return ret;
}
double sol(node a, node b, node c)
{
	return fabs(Xmul(jian(c, a), jian(c, b)) )/dis(a, b);
}
double test(node a1, node a2, node b1, node b2)
{
	double ret;
	ret=dis(a1, b1);
	ret = min(ret, dis(a1, b2));
	ret = min(ret, dis(a2, b1));
	ret = min(ret, dis(a2 ,b2));
	if( dcmp(mul(jian(a2, a1), jian(b1, a1)) )>=0 && dcmp(mul(jian(a1, a2), jian(b1, a2)) )>=0) ret = min(ret, sol(a1, a2, b1));
	if( dcmp(mul(jian(a2, a1), jian(b2, a1)) )>=0 && dcmp(mul(jian(a1, a2), jian(b2, a2)) )>=0) ret = min(ret, sol(a1, a2, b2));
	if( dcmp(mul(jian(b2, b1), jian(a1, b1)) )>=0 && dcmp(mul(jian(b1, b2), jian(a1, b2)) )>=0) ret = min(ret, sol(b1, b2, a1));
	if( dcmp(mul(jian(b2, b1), jian(a2, b1)) )>=0 && dcmp(mul(jian(b1, b2), jian(a2, b2)) )>=0) ret = min(ret, sol(b1, b2, a2));
	return ret;
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
	while(scanf("%d", &n)!=EOF)
	{
		for(int i=0; i<n; i++)
			scanf("%lf%lf", &nod1[i].x, &nod1[i].y);
		scanf("%d", &m);
		for(int i=0; i<m; i++)
			scanf("%lf%lf", &nod2[i].x, &nod2[i].y);
		nod1[n]=nod1[0]; nod2[m]=nod2[0];
		double ans=INF;
		for(int i=1; i<=n; i++)
			for(int j=1; j<=m; j++)
				ans= min(ans, test(nod1[i-1], nod1[i], nod2[j-1], nod2[j]));
		printf("%.4lf\n", ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值