2014新生暑假个人排位赛08

时间限制 1000 ms  内存限制 65536 KB

题目描述

小弱发明了一个好玩的游戏,游戏开始时给你一个凸多边形,这个多边形可以任意旋转,平移。让你造出一个正方形“容器”(足够大),容器的两边垂直,两边水平。用这个容器把这个多边形完全包含,且多边形有且只有一条边恰好与容器下边界重合(与外界相通),不同的边与外界相通代表不同的方案。现在让你判断是否有方案可以让这个多边形能够不掉下来。不掉下来要求是至少有一条边与容器之间存在压力(假设摩擦系数无穷大)。
如下图,左边会掉下来,右边不会掉下来。

输入格式

有多组数据。
对于每组数据,第一行是多边形点数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;
}


时间限制 1000 ms  内存限制 65536 KB

题目描述

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;
}


时间限制 1000 ms  内存限制 10000 KB

题目描述

学姐辛辛苦苦准备了一次讲座,讲课的过程中学姐数了一下人数,发现居然少到了一个学弟,学姐很生气,下决心要把这个学弟找出来。学姐开始点名了,为了快一点签到,学姐点名的时候只点大家的学号。学姐说:“这么简单的统计,几行就可以搞定,帮我写个程序吧,超过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
题目让输一个数N,和N-1个数。求1-N中没出现的那个。刚开始居然没注意N-1,以为可以有好几个没出现。。然后犯傻了。其实只要1-n的sum减去n-1个数的sum就可以了。


/*
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;
}







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值