寫在前面
要到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;
}
反思
不能怕麻煩。
多分幾步走。
如果怕麻煩反而可能更麻煩。。
欲速則不達,不要自以爲是。