由于 期末考试 代码敲得少了 (借口? 是的!!) 什么状态也没有, 一个 简单题目也能出各种奇葩 错误, 最近的各种比赛各种不顺畅, 很是不爽!!
我在瓶颈了? 思维 和 代码能力 都要提升!!不过多的 发出弱者的牢骚了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;
}