NOIP2014-7-7模拟赛

1.无线通讯网(wireless.pas/cpp/c)

【题目描述】

     国防部计划用无线网络连接若干个边防哨所。2种不同的通讯技术用来搭建无线网络;每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。

任意两个配备了一条卫星电话线路的哨所(两边都拥有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过D,这是受收发器的功率限制。收发器的功率越高,通话距离D会更远,但同时价格也会更贵。

收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个D。

你的任务是确定收发器必须的最小通话距离D,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)。

【输入格式】 wireless.in

第1行:2个整数S(1<=S<=100)和P(S<P<=500),S表示可安装的卫星电话的哨所数,P表示边防哨所的数量。

     接下里P行,每行描述一个哨所的平面坐标(x,y),以km为单位,整数,0<=x,y<=10000。

【输出格式】 wireless.out

第1行:1个实数D,表示无线电收发器的最小传输距离。精确到小数点后两位。

【样例输入】

 2 4

 0 100

 0 300

 0 600

 150 750

【样例输出】

212.13

 

数据范围

对于20%的数据  P=2,S=1

对于另外20%的数据  P=4,S=2

对于100%的数据  1<=S<=100,S<P<=500

 

 

 2.混合图(dizzy.pas/cpp/c)

【题目描述】

  Hzwer神犇最近又征服了一个国家,然后接下来却也遇见了一个难题。

  Hzwer的国家有n个点,m条边,而作为国王,他十分喜欢游览自己的国家。他一般会从任意一个点出发,随便找边走,沿途欣赏路上的美景。但是我们的Hzwer是一个奇怪的人,他不喜欢走到自己以前走过的地方,他的国家本来有p1条有向边,p2条无向边,由于国王奇怪的爱好,他觉得整改所有无向边,使得他们变成有向边,要求整改完以后保证他的国家不可能出现从某个地点出发顺着路走一圈又回来的情况。(注:m=p1+p2.)

  概述:给你一张混合图,要求你为无向图定向,使得图上没有环。

【输入格式】 dizzy.in

      第一行3个整数 n,p1,p2,分别表示点数,有向边的数量,无向边的数量。

      第二行起输入p1行,每行2个整数 a,b 表示a到b有一条有向边。

      接下来输入p2行,每行2个整数 a,b 表示a和b中间有一条无向边。

【输出格式】 dizzy.out

  对于每条无向边,我们要求按输入顺序输出你定向的结果,也就是如果你输出a b,那表示你将a和b中间的无向边定向为a->b。

  注意,也许存在很多可行的解。你只要输出其中任意一个就好。

【样例输入】

4 2 3

1 2

4 3

1 3

4 2

3 2

【样例输出】

1 3

4 2

2 3

 

数据范围

对于20%的数据 n<=10 p1<=10 p2<=5

对于30%的数据 n<=10 p1<=30 p2<=20

对于100%的数据 n<=100000 p1<=100000 p2<=100000

数据保证至少有一种可行解。

 

 3.小K的农场(farm.pas/cpp/c)

【题目描述】

     小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述:农场a比农场b至少多种植了c个单位的作物,农场a比农场b至多多种植了c个单位的作物,农场a与农场b种植的作物数一样多。但是,由于小K的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合。

【输入格式】 farm.in

     第一行包括两个整数n和m,分别表示农场数目和小K记忆中的信息数目。

     接下来m行:

     如果每行的第一个数是1,接下来有3个整数a,b,c,表示农场a比农场b至少多种植了c个单位的作物。

     如果每行的第一个数是2,接下来有3个整数a,b,c,表示农场a比农场b至多多种植了c个单位的作物。

     如果每行第一个数是3,家下来有2个整数a,b,表示农场a终止的数量和b一样多。

【输出格式】 farm.out

  如果存在某种情况与小K的记忆吻合,输出“Yes”,否则输出“No”。

【样例输入】

3 3

3 1 2

1 1 3 1

2 2 3 2

【样例输出】

Yes

 

样例解释:三个农场种植数量可以为(2,2,1)。

对于100%的数据  1<=n,m,a,b,c<=10000.


 T1:

最小生成树or二分并查集

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #include<cmath>
 7 #define MAXN 505
 8 using namespace std;
 9 struct Point{
10     double X,Y;
11 };
12 int S,V;
13 double d[MAXN][MAXN];
14 vector<double> s;
15 Point p[MAXN];
16 int f[MAXN];
17 int find(int x){
18     return (f[x]==x)?x:(f[x]=find(f[x]));
19 }
20 void lik(int x,int y){
21     x=find(x),y=find(y);
22     if(x!=y){
23         f[x]=y;
24     }
25 }
26 bool check(double c){
27     for(int i=1;i<=V;i++){
28         f[i]=i;
29     }
30     for(int i=1;i<=V;i++){
31         for(int j=i+1;j<=V;j++){
32             if(d[i][j]<=c){
33                 lik(i,j);
34             }
35         }
36     }
37     int b[MAXN]={0};
38     int cnt=0;
39     for(int i=1;i<=V;i++){
40         int x=find(i);
41         if(!b[x]){
42             b[x]=1;
43             cnt++;
44         }
45     }
46     return (cnt<=S);
47 }
48 int main()
49 {
50 //    freopen("data.in","r",stdin);
51     scanf("%d%d",&S,&V);
52     for(int i=1;i<=V;i++){
53         scanf("%lf%lf",&p[i].X,&p[i].Y);
54     }
55     for(int i=1;i<=V;i++){
56         for(int j=i+1;j<=V;j++){
57             double x1=p[i].X,y1=p[i].Y;
58             double x2=p[j].X,y2=p[j].Y;
59             d[i][j]=d[j][i]=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
60             s.push_back(d[i][j]);
61         }
62     }
63     sort(s.begin(),s.end());
64     int L=0,R=s.size()-1;
65     while(R-L>1){
66         int mid=(L+R)/2;
67         double c=s[mid];
68         if(check(c)){
69             R=mid;
70         }
71         else{
72             L=mid+1;
73         }
74     }
75     if(check(s[L]))
76         printf("%.2f\n",s[L]);
77     else
78         printf("%.2f\n",s[R]);
79     return 0;
80 }
Code1-1
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #define MAXN 505
 7 using namespace std;
 8 struct Edge{
 9     int x,y;
10     double Val;
11     Edge(int p1=0,int p2=0,double p3=0){
12         x=p1,y=p2,Val=p3;
13     }
14     friend bool operator < (const Edge &p1,const Edge &p2){
15         return (p1.Val<p2.Val);
16     }
17 };
18 int read(){
19     int x=0,f=1;char ch=getchar();
20     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
21     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
22     return x*f;
23 }
24 int s,n,cnt;
25 Edge p[MAXN*MAXN];
26 int X[MAXN],Y[MAXN];
27 int f[MAXN];
28 double dist(int a,int b){
29     double x1=X[a],y1=Y[a];
30     double x2=X[b],y2=Y[b];
31     return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
32 }
33 int find(int x){
34     return (f[x]==x)?x:(f[x]=find(f[x]));
35 }
36 int main()
37 {
38 //    freopen("data.in","r",stdin);
39     s=read();n=read();
40     for(int i=1;i<=n;i++){
41         f[i]=i;
42     }
43     for(int i=1;i<=n;i++){
44         X[i]=read();
45         Y[i]=read();
46     }
47     for(int i=1;i<=n;i++){
48         for(int j=i+1;j<=n;j++){
49             p[++cnt]=Edge(i,j,dist(i,j));
50         }
51     }
52     sort(p+1,p+cnt+1);
53     int t=0;
54     int i;
55     for(i=1;i<=cnt;i++){
56         int x=p[i].x,y=p[i].y;
57         x=find(x),y=find(y);
58         if(x!=y){
59             f[x]=y; t++;
60         }
61         if(t+s==n){
62             break;
63         }
64     }
65     printf("%.2f\n",p[i].Val);
66     return 0;
67 } 
Code1-2

T2:

拓扑排序

 1 //尚未测评(SJ)
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<vector>
 7 #define MAXN 100005
 8 using namespace std;
 9 int n,p1,p2;
10 int first1[MAXN],Next1[MAXN],to1[MAXN],cnt1;
11 int degree[MAXN];
12 int b[MAXN];
13 vector<int> vs;
14 int pre[MAXN];
15 void Add1(int x,int y){
16     Next1[++cnt1]=first1[x];first1[x]=cnt1;to1[cnt1]=y;
17 }
18 int read(){
19     int x=0,f=1;char ch=getchar();
20     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
21     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
22     return x*f;
23 }
24 void dfs(int x){
25     b[x]=1;
26     vs.push_back(x);
27     for(int e=first1[x];e;e=Next1[e]){
28         int y=to1[e];
29         if(!b[y]){
30             dfs(y);
31         }
32     }
33 }
34 int main()
35 {
36 //    freopen("data.in","r",stdin);
37     n=read();p1=read();p2=read();
38     for(int i=1;i<=p1;i++){
39         int x,y;
40         x=read();y=read();
41         Add1(x,y);
42         degree[y]++;
43     }
44     for(int i=1;i<=n;i++){
45         if(!degree[i]){
46             dfs(i);
47         }
48     }
49     for(int i=0;i<vs.size();i++){
50         int x=vs[i];
51         pre[x]=i;
52     }
53     for(int i=1;i<=p2;i++){
54         int x,y;
55         x=read();y=read();
56         if(pre[x]<pre[y]){
57             printf("%d %d\n",x,y);
58         }
59         else{
60             printf("%d %d\n",y,x);
61         }
62     }
63     return 0;
64 } 
Code2

T3:

差分+正环判断

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #define MAXN 10005
 6 using namespace std;
 7 int first[MAXN],Next[MAXN*2],to[MAXN*2],Val[MAXN*2],cnt;
 8 int n,m;
 9 int b[MAXN],d[MAXN];
10 void Add(int x,int y,int w){
11     Next[++cnt]=first[x];first[x]=cnt;to[cnt]=y;Val[cnt]=w;
12 }
13 int read(){
14     int x=0,f=1;char ch=getchar();
15     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
16     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
17     return x*f;
18 }
19 int SPFA(int x){
20     if(b[x]){
21         return 1;
22     }
23     b[x]=1;
24     for(int e=first[x];e;e=Next[e]){
25         int y=to[e],w=Val[e];
26         if(d[y]<d[x]+w){
27             d[y]=d[x]+w;
28             if(SPFA(y))
29                 return 1;
30         }
31     }
32     b[x]=0;
33     return 0;
34 }
35 int main()
36 {
37 //    freopen("data.in","r",stdin);
38     n=read();
39     m=read();
40     for(int i=1;i<=m;i++){
41         int p=read();
42         if(1==p){
43             int x=read(),y=read(),w=read();
44             Add(x,y,w);
45         }
46         else if(2==p){
47             int x=read(),y=read(),w=read();
48             Add(y,x,-w);
49         }
50         else{
51             int x=read(),y=read();
52             Add(x,y,0);
53             Add(y,x,0);
54         }
55     }
56     for(int i=1;i<=n;i++){
57         memset(d,0,sizeof(d));
58         if(SPFA(i)){
59             printf("No\n");
60             return 0;
61         }
62     }
63     printf("Yes\n");
64     return 0;
65 }
Code3

 

posted @ 2017-10-14 23:50  white_hat_hacker  阅读(173)  评论(0编辑  收藏  举报