18.3.1

寫在前面

要到3.3纔開學,這幾天在機房進入福州集訓模式。。。
就是上午考試,下午講,然後自己敲代碼。
其實感覺還行。。
昨天的到時候補上,因爲T4老劉數據不正確。所以不能算完成。
情況如圖
這裏寫圖片描述
這裏寫圖片描述
啊!瘋狂掉Rating。。
看題目吧。

T1

題面

1.簡單題
(zizhen.pas/c/cpp)
【問題描述】
給定數軸上的N個點,求這些點到其他點的距離總和S。

【輸入】
第一行一個整數N。
接下來N行每行一個整數,表示每個點的座標xi。

【輸出】
一個整數S。

【輸入輸出樣例1】
zizhen.in zizhen.out
5
1
5
3
2
4 40

【輸入輸出樣例2】
zizhen.in zizhen.out
8
10
20
30
40
50
60
70
80 1680

【數據範圍】
對於30%的數據,1≤N≤10000
對於50%的數據,保證1≤xi。
對於70%的數據,保證1≤N≤300000,且任意兩點的座標不相同。
對於100%的數據,保證1≤N≤3000000,|xi|≤2^15-1。

描述

就是求每點與其他點距離總和。。
我的解法有點像差分。
利用各數排序後的差值。
有差值也就是右邊比左邊普遍高這麼多。也就是總距離加上(差值乘以i乘以(n-i)再乘上2)就可以了。

題解

#include<bits/stdc++.h>
using namespace std;
inline long long read()
{
    long long sum=0;char c=getchar();
    for(;c<'0'||c>'9';c=getchar());
    for(;c<='9'&&c>='0';c=getchar())
      sum=(sum<<1)+(sum<<3)+c-48;
    return sum;
}
long long n,ans=0;
long long a[3000010]={};
void init()
{
    n=read();
    for(int i=1;i<=n;i++)
      a[i]=read();
}
void work()
{
    sort(a+1,a+n+1);
    for(int i=1;i<n;i++)
      a[i]=a[i+1]-a[i];
    for(int i=1;i<n;i++)
      ans+=a[i]*i*(n-i)*2;
}
int main()
{
    init();
    work();
    cout<<ans;
    return 0;
}

反思

。。。
爲什麼我只有60??
因爲a數組的3000010.
我寫成了300010!!!
一波失誤。。。
不能再錯。

T2

題面

2.激光通訊
(laser.pas/c/cpp)
【問題描述】
海亮教育園的oiers有了新的通訊工具,採用最先進的系統——激光通訊系統,這樣可以讓他們在整個校園無延時的進行通訊。
海亮教育園校園被設計爲由W*H個點組成的網格。(1 <= W <= 100; 1 <= H <= 100)這套系統要求類似視線連通以確保維持通訊,當然了,校園裏還有一些建築和樹,這些東西會干擾通訊,但是oiers早有準備,他們購買了一些斜放的反光鏡(如下圖中的”/”和”\”),這些鏡子能通過反射把激光束扭轉90度,下面是問題的一個圖解。
在這個地圖中H=8,W=7,正在通訊的兩名oiers用符號”C”表示,可通訊區域用”.”表示,障礙物用”*”表示:
這裏寫圖片描述
確定最少需要安放幾個反光鏡(數目用M表示),才能保證這兩個人之間的激光通訊,注意所給的數據一定有解。

【輸入】
第1行有兩個空格隔開的整數:W,H;
第2~H+1行爲完整的校園。
【輸出】
一行,一個整數M,即反光鏡的個數。
【輸入輸出樣例1】
laser.in
7 8
…….
……C
……*
.
….*..
….*..
.C..*..
…….

laser.out
3

【數據範圍】
30% n,m<=30.
50% n,m<=50

描述

就是可以使用平面鏡改變通訊方向。
求需要最少幾隻鏡子,能到達終點。
根據題解才知道,使用改版的bloodfill。。
每次bfs同行同列的進行染色。
這樣的話很容易可以求出。
這裏寫圖片描述

題解

#include<bits/stdc++.h>
using namespace std;
int m,n,xx,yy;
char a[110][110];
bool vis[110][110]={};
struct note
{
    int x,y,sum;
}q[1000010];
void init()
{
    char c;
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
      {
        c=getchar();
        for(int j=1;j<=m;j++)
          {
            a[i][j]=getchar();
            if (a[i][j]=='C')
              xx=i,yy=j;
          }
      }
    for(int i=1;i<=m;i++)
      a[0][i]='*',a[n+1][i]='*';
    for(int i=1;i<=n;i++)
      a[i][0]='*',a[i][m+1]='*';
}
void work()
{
    int head=0,tail=1;
    q[1].x=xx;
    q[1].y=yy;
    q[1].sum=0;
    vis[xx][yy]=1;
    while (++head<=tail)
      {
        for(int i=q[head].x;i<=n;i++)
          if (!vis[i][q[head].y])
          {
            if (a[i][q[head].y]=='*')
              break; 
            if (a[i][q[head].y]=='C')
              {
                  cout<<q[head].sum;
                  return ;
              }
            q[++tail].x=i;
            q[tail].y=q[head].y;
            q[tail].sum=q[head].sum+1;
            vis[i][q[head].y]=1;
          }
        for(int i=q[head].x;i>=1;i--)
          if (!vis[i][q[head].y])
          {
            if (a[i][q[head].y]=='*')
              break;
            if (a[i][q[head].y]=='C')
              {
                  cout<<q[head].sum;
                  return ;
              }
            q[++tail].x=i;
            q[tail].y=q[head].y;
            q[tail].sum=q[head].sum+1;
            vis[i][q[head].y]=1;
          }
        for(int i=q[head].y;i>=1;i--)
          if (!vis[q[head].x][i])
          {
            if (a[q[head].x][i]=='*')
              break;
            if (a[q[head].x][i]=='C')
              {
                  cout<<q[head].sum;
                  return ;
              }
            q[++tail].x=q[head].x;
            q[tail].y=i;
            q[tail].sum=q[head].sum+1;
            vis[q[head].x][i]=1;
          }
        for(int i=q[head].y;i<=m;++i)
          if (!vis[q[head].x][i])
          {
            if (a[q[head].x][i]=='*')
              break;
            if (a[q[head].x][i]=='C')
              {
                  cout<<q[head].sum;
                  return ;
              }
            q[++tail].x=q[head].x;
            q[tail].y=i;
            q[tail].sum=q[head].sum+1;
            vis[q[head].x][i]=1;
          }
      }
}
int main()
{
    init();
    work();
    return 0;
}

T3

題面

3.巡邏
(patrol.pas/c/cpp)
【問題描述】
海亮教育園的保衛科每天晚上都要進行巡邏,而實驗樓是機房所在地,是要必須巡邏的。
爲了更好的描述問題,現在我們把海亮教育園抽象成一個圖,這個圖有N個點,M條有向邊,保衛科在1號點,一號實驗樓在2號點。每天巡邏必須從1號點出發,到達2號點再回到1號點,當然這個路徑是包含自己選擇的。
因爲今天只有1個保安,沒有其他人監督,並且在晚上一個人巡邏是很痛苦的事情,現在他想要在巡邏的過程中,經過的不同的點的個數最小,如果能完成這個任務,你的rp可以增加!
【輸入】
第一行有兩個整數N和M (2 ≤ N ≤ 100, 2 ≤ M ≤ 200)。
接下來M行,每行兩個整數A和B (1 ≤ A, B ≤ N),保證不會有重邊。

【輸出】
只有1個整數,表示最少經過的不同的點的個數。

【輸入輸出樣例1】
patrol.in patrol.out
6 7
1 3
3 4
4 5
5 1
4 2
2 6
6 3 6
{路徑是1 -> 3 -> 4 -> 2 -> 6 -> 3 -> 4
-> 5 -> 1. 經過6個城市。}
【輸入輸出樣例2】
patrol.in
9 11
1 3
3 4
4 2
2 5
5 3
3 6
6 1
2 7
7 8
8 9
9 1

patrol.out
6
【數據範圍】
20%數據保證 N<=20.

描述

dfs先找2,再找1.
求一個路徑經過最少點。

題解

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int sum=0;char c=getchar();
    for(;c<'0'||c>'9';c=getchar());
    for(;c<='9'&&c>='0';c=getchar())
      sum=(sum<<1)+(sum<<3)+c-48;
    return sum;
}
int t=0,n,m,ans=100000000;
struct note
{
    int y,next;
}a[210];
int linkk[110]={};
bool vis[110]={};
bool f[110]={};
void insert(int x,int y)
{
    a[++t].y=y;
    a[t].next=linkk[x];
    linkk[x]=t;
}
void init()
{
    n=read();
    m=read();
    int x,y;
    for(int i=1;i<=m;i++)
      {
        x=read();
        y=read();
        insert(x,y);
      }
}
void dfs2(int now,int sum)
{
    if (sum>=ans) return ;
    if (now==1)
      {
        ans=min(ans,sum);
        return ;
      }
    for(int i=linkk[now];i;i=a[i].next)
        if (!vis[a[i].y])
        {
          vis[a[i].y]=1;
          if (!f[a[i].y]) dfs2(a[i].y,sum+1);
            else dfs2(a[i].y,sum);
          vis[a[i].y]=0;
        }
}
void dfs1(int now,int sum)
{
    if (sum+1>=ans) return ;
    if (now==2)
      {
        memset(vis,0,sizeof(vis));
        vis[2]=1;
        dfs2(now,sum);
        return ;
      }
    for(int i=linkk[now];i;i=a[i].next)
        if (!f[a[i].y]) 
          {
            f[a[i].y]=1;
            dfs1(a[i].y,sum+1);
            f[a[i].y]=0;
          }
}
int main()
{
    init();
    f[1]=1;
    dfs1(1,1);
    cout<<ans;
    return 0;
}

反思

不能怕麻煩。
多分幾步走。
如果怕麻煩反而可能更麻煩。。
欲速則不達,不要自以爲是。

發佈了49 篇原創文章 · 獲贊 11 · 訪問量 8591
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章