1. 程式人生 > >第一次爆零

第一次爆零

技術分享 還需要 stdin nod 範圍 博文 平面 相交 clu

前言:打代碼慢沒關系,除非你不用心

一開始打了好多,但由於孫姓同學(gavensun.com)運行了一個惡意程序,然後本篇博文並沒有保存,所以前言就說這麽多

第一題,註意數據範圍,不要吊兒郎當

第二,三題(並查集求聯通塊:不要亂寫,撞對垃圾樣例並不一定對

2

 道路

                1000ms/128MB
  M市有 n個城鎮,同時有 m條道路(無向),城鎮之間可以通過一條或多條道路到達。為了全面建設小
  康社會,現要新建設一些道路,使得所有城鎮之間兩兩可以互相到達。
  請你計算出最少還需要建設多少條道路

  輸入格式:
  第一行:兩個正整數,分別是城鎮數目 n(n<1000)和道路數目 m(m <= n * (n – 1)/2));隨後的
  m行對應 m條道路,每行給出兩個正整數,分別是道路相連的兩個城鎮編號。城鎮從 1到 N編號。
  兩個城市間可以有多條道路相通。

  輸出格式:一行一個整數。為最少需要建設的道路。

   

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define DEEEEEEEE
 4 using namespace std;
 5 const int MAXN = 1000+9;
 6 const int MAXM = 500000+9;
 7 
 8 int n,m,ans;
 9 int fa[MAXN];
10 bool
visit[MAXN]; 11 12 int father(int x) { 13 if(x == fa[x]) return x; 14 return fa[x] = father(fa[x]); 15 } 16 17 int main() { 18 #ifdef DEEEEEEEE 19 freopen("b.in","r",stdin); 20 freopen("b.out","w",stdout); 21 #endif 22 scanf("%d%d",&n,&m); 23
for(int i = 1; i <= n; i++) fa[i] = i; 24 int fx,fy; 25 for(int i = 1, x, y; i <= m; i++) { 26 scanf("%d %d",&x,&y); 27 fx = father(x), fy = father(y); 28 fa[fx] =fy;//把道路的代表元素聯通 29 } 30 for(int i = 1; i <= n; i++) { // 求聯通塊個數 31 if(!visit[father(i)]) {//先寫father(i) 這才把fa[i]算出來 32 visit[fa[i]] = 1; 33 ans++; 34 } 35 } 36 printf("%d",ans-1);//ans個聯通塊,最少需要連ans-1條道路 37 return 0; 38 }

3.

  現在一個平面上畫了 n 個矩形。每一個矩形的兩邊都與坐標軸相平行,且矩形定點的坐標均為整數。現定
  義滿足如下性質的圖形為一個塊:
  1. 每一個矩形都是一個塊;
  2. 如果兩個塊有一段公共的部分,那麽這兩個塊就會形成一個新的塊,否則這兩個塊就是不同的。
  示例:
  圖 1矩形形成了兩個不同的塊。圖 2矩形形成了一個塊。

技術分享圖片技術分享圖片

找不同塊的個數

#include<cstdio>
#include<algorithm>
#define DEEEEEEEE
using namespace std;
const int MAXN = 7000+9;
int n,ans;
int fa[MAXN];
bool visit[MAXN];

int father(int x) {
    if(x == fa[x]) return x;
    return fa[x] = father(fa[x]);
}

struct node{
    int x1,y1,x2,y2;
}e[MAXN];

bool judge(int x1,int y1, int x2, int y2, int x111, int y111, int x222, int y222) {
    //找關系的時候冷靜一點,不要慌 
    if(x2<x111 || x1>x222 || y1>y222 || y2<y111 ) return 0;//沒有一點相交 
    if( (x1==x222 || x2==x111) && (y1==y222 || y2==y111) ) return 0;//相交一點 
    return 1;
}

int main() {
    #ifdef DEEEEEEEE
        freopen("c.in","r",stdin);
        freopen("c.out","w",stdout);
    #endif
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) fa[i] = i;
    int x1,y1,x2,y2,x111,y111,x222,y222;
    // 矩形1號         矩形2號 
    int f1,f2;
    for(int i = 1; i <= n; i++) {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        e[i].x1 = x1, e[i].x2 = x2, e[i].y1 = y1, e[i].y2 = y2;
        for(int j = 1; j < i; j++) {
            x111 = e[j].x1 , y111 = e[j].y1 , x222 = e[j].x2 , y222 = e[j].y2 ;
            if(judge(x1,y1,x2,y2,x111,y111,x222,y222) ) {
                f1 = father(i), f2 = father(j);
                fa[f1] = f2;
            }
        }
    } 
    for(int i = 1; i <= n; i++) {
        if(!visit[father(i)]) {
            visit[fa[i]] = 1;
            ans++;
        }
    }
    printf("%d",ans);
    return 0;
 }

第四題:分層圖(仔細分析題目,不要看見那麽多的條件就害怕

            消失的 c題(c.cpp/c.in/c.out)
            1000ms/128MB
  題目描述
  N 個蟲洞,M 條單向躍遷路徑。從一個蟲洞沿躍遷路徑到另一個蟲洞需要消耗一定量的燃料和 1 單
  位時間。蟲洞有白洞和黑洞之分。設一條躍遷路徑兩端的 蟲洞質量差為 delta。
  1.從白洞躍遷到黑洞,消耗的燃料值減少 delta,若該條路徑消耗的燃料值變為負數的話,取為 0。
  2.從黑洞躍遷到白洞,消耗的燃料值增加 delta。
  3.路徑兩端均為黑洞或白洞,消耗的燃料值不變化。
  每過 1 單位時間黑洞變為白洞,白洞變為黑洞。
  在飛行過程中,可以選擇在一個蟲洞停留 1 個單位時間,如果當前為白洞,則不消耗燃料,否則消
  耗 s[i]的燃料。現在請你求出從 蟲洞 1 到 N 最少的燃料消耗,保證一定存在 1 到 N 的路線。

  輸入格式

  第 1 行:2 個正整數 N,M
  第 2 行:N 個整數,第 i 個為 0 表示蟲洞 i 開始時為白洞,1 表示黑洞。
  第 3 行:N 個整數,第 i 個數表示蟲洞 i 的質量 w[i]。
  第 4 行:N 個整數,第 i 個數表示在蟲洞 i 停留消耗的燃料 s[i]。

  第 5..第 M+4 行:每行 3 個整數,u,v,k,表示在沒有影響的情況下,從蟲洞 u到蟲洞 v 需要消耗燃料 k。


  輸出格式
  一個整數,表示最少的燃料消耗。

  樣例輸入
  4 5
  1 0 1 0
  10 10 100 10
  5 20 15 10
  1 2 30
  2 3 40
  1 3 20
  1 4 200
  3 4 200

  

  樣例輸出
  130

  數據範圍
  對於 30%的數據: 1<=N<=100,1<=M<=500
  對於 60%的數據: 1<=N<=1000,1<=M<=5000
  對於 100%的數據: 1<=N<=5000,1<=M<=30000
  其中 20%的數據為 1<=N<=3000 的鏈
  1<=u,v<=N, 1<=k,w[i],s[i]<=200

  樣例說明
  按照 1->3->4 的路線。

第一次爆零