1. 程式人生 > >NOIP2014-7-7模擬賽

NOIP2014-7-7模擬賽

void 搭建 出現 out isp nbsp cstring one ble

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

NOIP2014-7-7模擬賽