写在前面
要到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;
}
反思
不能怕麻烦。
多分几步走。
如果怕麻烦反而可能更麻烦。。
欲速则不达,不要自以为是。