A. 游戏 2014新生暑假个人排位赛08
题目描述
小弱发明了一个好玩的游戏,游戏开始时给你一个凸多边形,这个多边形可以任意旋转,平移。让你造出一个正方形“容器”(足够大),容器的两边垂直,两边水平。用这个容器把这个多边形完全包含,且多边形有且只有一条边恰好与容器下边界重合(与外界相通),不同的边与外界相通代表不同的方案。现在让你判断是否有方案可以让这个多边形能够不掉下来。不掉下来要求是至少有一条边与容器之间存在压力(假设摩擦系数无穷大)。
如下图,左边会掉下来,右边不会掉下来。
输入格式
有多组数据。
对于每组数据,第一行是多边形点数n(3 <= n <= 1000),后面n行分别是这些点沿着多边形逆时针的二维坐标(xi, yi)(xi,yi的绝对值 <= 1000,输入数据精度精确到两位)。
输出格式
对每组数据输出有多少种方案可以使多边形不掉下来。
输入样例
3
0.00 0.00
2.00 0.00
1.00 1.00
3
0.00 0.00
1.00 0.00
2.00 1.00
4
0.00 0.00
4.00 0.00
3.00 2.00
1.00 2.00
输出样例
0
2
3
当时一看就想到了是锐角,但是没有判重,所以wa了几次。
/*
USER_ID: test#wlwlxgg
PROBLEM: 448
SUBMISSION_TIME: 2014-07-30 15:28:28
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef pair<float,float> P;
bool dunjiao(P x,P y,P z){
P a,b;
a.first=x.first-y.first;
a.second=x.second-y.second;
b.first=z.first-y.first;
b.second=z.second-y.second;
if(a.first*b.first+a.second*b.second<0)
return true;
return false;
}
int main()
{
int n;
P q[1010];
while(~scanf("%d",&n)){
float x,y;
for(int i=0;i<n;i++){
scanf("%f%f",&x,&y);
q[i]=make_pair(x,y);
}
int ans=0;
for(int i=0;i<n-2;i++)
if(dunjiao(q[i],q[i+1],q[i+2]))
ans++;
if(dunjiao(q[n-2],q[n-1],q[0])) ans++;
if(dunjiao(q[n-1],q[0],q[1])) ans++;
int cc=0;
for(int i=0;i<n-3;i++)
if(dunjiao(q[i],q[i+1],q[i+2])&&dunjiao(q[i+1],q[i+2],q[i+3]))
cc++;
if(dunjiao(q[n-2],q[n-1],q[0])&&dunjiao(q[n-3],q[n-2],q[n-1])) cc++;
if(dunjiao(q[n-2],q[n-1],q[0])&&dunjiao(q[n-1],q[0],q[1])) cc++;
if(dunjiao(q[n-1],q[0],q[1])&&dunjiao(q[0],q[1],q[2])) cc++;
if(ans==0) printf("%d\n",ans);
else
printf("%d\n",ans*2-cc);
}
return 0;
}
B. 小妹妹送快递 2014新生暑假个人排位赛08
题目描述
Mays王国的女王大人每天过着自由自在的生活,她最大的乐趣就是给邻国的帅气王子写信。但是最近,Mays王国的叔叔们变得很无聊,他们知道女王大人每次都把信委托给皇家小妹妹快递公司的小妹妹们,于是叔叔们给每一条路都设立了路障,只有小妹妹们给他们表演节目才会让小妹妹们过去。
在每一个路障,都有不同数量的叔叔,只有表演的小妹妹的数量不少与叔叔的数量的时候叔叔才会放她们过去。
为了节省开销,小妹妹快递公司希望派最少的小妹妹把女王大人的信件送到。请你告诉他们需要派几个小妹妹。
输入格式
输入第一行为数据组数T(T<=10),接下来T组数据,每组第一行为n,m,,2<=n<=10000,1<=m<=100000,表示Mays王国的道路由n个节点组成,接下来m行,每行一组u,v,c表示连接节点u,v的一条无向道路,且路障上有c个叔叔,1<=u,v<=n,0<=c<=100。女王大人和皇家小妹妹快递公司都在节点1,帅气的邻国王子住在节点n。
输出格式
每组数据输出一个数字,表示小妹妹快递公司最少需要派出的小妹妹数量。如果无论派出多少小妹妹都无法把信送到帅气的邻国王子手里,输出"shimatta!"。
输入样例
1
3 3
1 2 1
2 3 1
1 3 3
输出样例
1
有n个结点,起点1,终点n。有m条边,每条边有一个权值,求从起点到终点所有路径中权值最大的边的权值的最小值。
一,spfa, d[v]=max(e[i].cost,d[u])
/*
USER_ID: test#wlwlxgg
PROBLEM: 468
SUBMISSION_TIME: 2014-07-31 00:55:55
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
#include <cmath>
#define MAXE 200010
#define MAXV 10010
#define INF 1000000000
using namespace std;
struct {int to,next,cost;}e[MAXE];
int head[MAXV],vis[MAXV],d[MAXV],cnt;
int n,m;
void add_edge(int u,int v,int cost){
e[cnt].to=v;
e[cnt].cost=cost;
e[cnt].next=head[u];
head[u]=cnt++;
}
void SPFA(int s){
for(int i=1;i<=n;i++)
d[i]=INF;
memset(vis,0,sizeof(vis));
queue<int> que;
d[s]=0;
que.push(s);
vis[s]=1;
while(!que.empty()){
int u=que.front();
que.pop();
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(d[v]>max(e[i].cost,d[u])){
d[v]=max(e[i].cost,d[u]);
if(!vis[v]){
vis[v]=1;
que.push(v);
}
}
}
vis[u]=0;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(head,0,sizeof(head));
cnt=1;
int u,v,cost;
for(int i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&cost);
add_edge(u,v,cost);
add_edge(v,u,cost);
}
SPFA(1);
if(d[n]==INF) puts("shimatta!");
else if(d[n]==0) printf("1\n");
else printf("%d\n",d[n]);
}
return 0;
}
二,把边从小到大排序,用并查集,当find(1)==find(n),时,输出此时的边的cost.
/*
USER_ID: test#wlwlxgg
PROBLEM: 468
SUBMISSION_TIME: 2014-08-03 14:23:44
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#define MAX_E 100010
#define MAX_V 10010
using namespace std;
struct edge {int u,v,cost;};
edge e[MAX_E];
int n,m;
int father[MAX_V];
int find(int x){
if(x==father[x]) return x;
else return father[x]=find(father[x]);
}
void unite(int x,int y){
x=find(x),y=find(y);
if(x==y)return ;
father[x]=y;
}
bool cmp(const edge& a,const edge& b){
return a.cost<b.cost;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].cost);
if(e[i].cost==0) e[i].cost=1;
}
sort(e,e+m,cmp);
for(int i=0;i<=n;i++)
father[i]=i;
for(int i=0;i<m;i++){
unite(e[i].u,e[i].v);
if(find(1)==find(n)){
printf("%d\n",e[i].cost);
break;
}
}
}
return 0;
}
C. 学姐点名 2014新生暑假个人排位赛08
题目描述
学姐辛辛苦苦准备了一次讲座,讲课的过程中学姐数了一下人数,发现居然少到了一个学弟,学姐很生气,下决心要把这个学弟找出来。学姐开始点名了,为了快一点签到,学姐点名的时候只点大家的学号。学姐说:“这么简单的统计,几行就可以搞定,帮我写个程序吧,超过500B的运行时间又在1ms以上的我不要”。
oj的功能出了点问题,内存判定没有效果,代码长度限制也没有效果。oj上显示超过528B的代码,比赛结束前时限直接调成1ms手工重新判定。(换句话说,本地代码大小超过500B的AC不算。)
输入格式
每组数据第一行一个数N,接下来N-1行每行一个数字表示学弟的学号。
多组数据,eof结束。
2组数据N为1000000
500组数据满足N不大于3000
1000组数据满足N不大于10
输出格式
输出没到的学弟的学号
输入样例
3
1
3
2
1
输出样例
2
2
/*
USER_ID: test#wlwlxgg
PROBLEM: 472
SUBMISSION_TIME: 2014-07-30 16:23:23
*/
#include <iostream>
#include <cstdio>
using namespace std;
long long sum[1000000];
int main()
{
int n;
sum[1]=1;
for(int i=2;i<=1000000;i++)
sum[i]=sum[i-1]+i;
while(~scanf("%d",&n)){
long long tot=0;
int x;
for(int i=1;i<n;i++){
scanf("%d",&x);
tot+=x;
}
printf("%d\n",sum[n]-tot);
}
return 0;
}