1. 水水の题
[问题描述]
嗯……水水的题。 ti。梯。电梯? emmmmm……
那么,有一座电梯,它上升一层需要 6 秒钟,下降一层需要 4 秒钟,如果
要让它停下,它会停 5 秒钟。
现在告诉你,它要按顺序到达然后停靠的 N 个楼层,求它需要的时间。
电梯开始在 0 层,楼梯共有 100 层。
[输入格式]
输入包含 N+1 行。
第一行为 N,接下来的 N 行是它 N 个停靠的楼层。
[输出格式]
输出包含一行。
第一行一个整数, 为所需要的时间。。
[样例输入]
3 2 3 1
[样例输出]
41
[样例说明]
NULL
[数据规模与约定]
N<=50。
题解:
直接模拟,上升即为层数的差值乘上6加上5,下降即为层数的差值乘上4加上5。
CODE
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100
int a[MAXN];
int n,ans=0;
void read(int &readnum)
{
int s=0,w=1;char c=getchar();
while (c<'0' || c>'9') {if (c=='-') w=-1;c=getchar();}
while (c>='0' && c<='9') s=s*10+c-48,c=getchar();
readnum=s*w;
}
int main()
{
freopen("ti.in","r",stdin);
freopen("ti.out","w",stdout);
read(n);
for (int i=1;i<=n;++i) read(a[i]);
int now=0;
for (int i=1;i<=n;++i)
{
if (a[i]>now) ans+=6*(a[i]-now)+5;
else ans+=4*(now-a[i])+5;
now=a[i];
}
cout<<ans<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
2. 水水の数
[问题描述]
一天,无聊的水水在纸上的不同位置写着一个又一个数字。最终,水水一
共写了 N 个数字,每个数字书写位置的坐标分别为(xi,yi)。
看着纸上的数字,水水突然脑洞大开。定义一个数字到另一个数字的“水
氏距离”为两个数字在竖直方向上的差值。水水想在所有的数字中找到一个数
字,这个数字满足其他所有数字到它的“水氏距离”之和最短。
然而,由于满足条件的数字可能不止一个。因此,水水只想知道其他所有
数字到这个数字的“水氏距离”之和。
[输入格式]
输入包含 N+1 行。
第一行一个整数 N。
之后 N 行, 每行两整数 xi,yi 表示第 i 个数字被写在坐标(xi,yi)处。
[输出格式]
输出包含 1 行。
第一行一个整数,即所求“水氏距离”之和。
[样例输入]
5
1 2
2 2
1 3
3 -2
3 3
[样例输出]
6
寻找中位数。
对于奇数:a[n/2+1]一定是最终的答案。
对于偶数:a[n/2]~a[n/2+1]的区间范围一定是最终的答案。
可以根据绝对值的几何意义进行证明。
#include<bits/stdc++.h>
using namespace std;
#define MAXN 2000000
int a[MAXN];
void read(int &readnum)
{
int s=0,w=1;char c=getchar();
while (c<'0' || c>'9') {if (c=='-') w=-1;c=getchar();}
while (c>='0' && c<='9') s=s*10+c-48,c=getchar();
readnum=s*w;
}
int main()
{
freopen("num.in","r",stdin);
freopen("num.out","w",stdout);
int n;
read(n);
for (int i=1;i<=n;++i)
{
int x,y;
read(x);
read(y);
a[i]=y;
}
sort(a+1,a+n+1);
int ans=0;
for (int i=1;i<=n;++i) ans+=abs(a[i]-a[n/2+1]);
cout<<ans<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
3. 水水の字
[问题描述]
水水是一名出色的 OIer,在训练过程中,他发现各大 OJ 并不是很好用,
于是决定自己建立一个 OJ。 可是水水希望在建立 OJ 系统之前了解他一共要创
建多少个文件夹。
在即将构建 OJ 的 Linux 系统下可以用路径来描述文件夹,路径为一个包
含若干部分的字符串,之间用“/”(不含引号)分隔。每部分均为一个文件夹
的名称,且表示这个文件夹的父文件夹为前一部分描述的文件夹。每个路径的
第 1 个字符总是“/”,且不会出现两个连续的“/”,最后一个字符不会是“/”。
而所有文件夹仅包含数字和字母。
例如: /home/fj/summer 表示根目录下有一个名称为 home 的文件夹,
这个 home 文件夹下有一个名称 fj 的文件夹,这个名称为 fj 的文件夹下有一
个名称为 summer 的文件夹。此时要构造出这样的路径关系,除根目录外还需
要 3 个文件夹。
现在先给出 N 个路径,一开始除了根目录不存在任何文件夹,在每给出一
个路径后,对于第 i 个路径,你需要输出的是若要让第 1 个路径到第 i 个路径
存在,最少需要新建多少个文件夹。
[输入格式]
输入包含 N+1 行。
输入文件第 1 行为一个正整数 N。
接下来 N 行,每行为一个描述路径的字符串,长度均不超过 100。
[输出格式]
输出包含 N 行。
每行 1 个正整数,第 i 行输出若要使第 1 个路径到第 i 个路径存在,最少
需要新建多少个文件夹。
[样例输入]
6
/data
/data/build
/data/eat
/data/build
/build/build
/data
[样例输出]
1
2
3
3
5
5
STL MAP
对于每一个文件,当且仅当所有上级节点的文件都相同才表示重复。
因此我们可以设置Map,把当前文件以及它的所有上级文件作为一个字符串存入Map中,如果在Map中存在这个数字就说明是重复的,否则就需要添加文件。
CODE
#include<bits/stdc++.h>
using namespace std;
char s[2000][2000];
map<string,bool>v;
int main()
{
freopen("dir.in","r",stdin);
freopen("dir.out","w",stdout);
int n,ans=0;
cin>>n;
for (int i=1;i<=n;++i) cin>>s[i];
for (int i=1;i<=n;++i)
{
string temp;
int len=strlen(s[i]);
for (int j=0;j<len;++j)
{
temp+=s[i][j];
if (s[i][j+1]=='/' || j==len-1)
if (!v[temp]) ans++,v[temp]=1;
}
cout<<ans<<endl;
}
fclose(stdin);
fclose(stdout);
return 0;
}
4. 水水の图
[问题描述]
水水将去 K 国旅游。 K 国有 N 个省份,其中, 1 号省份是首都。
N 个省份之间有 M 趟火车,火车是双向的。定义第 i 个省份的转车次数为
从首都到这个省份,最少需要转几趟火车。如果从首都无法到达 i 省份,那么
i 省份的转车次数是无穷大。
由于洪水等自然原因,有些火车会停运。
当一趟火车停运之后, 2~N 每个省份的转车次数不变,这种情况水水尚且
可接受,否则,水水则可能取消这次旅行。
现在水水想提前知道,哪些火车的停运是可接受的?以便提早做出旅行决
定。 如果可接受的火车不存在,输出一行“NO”(不含引号)。
[输入格式]
输入包含 M+1 行。
第一行两个正整数 N, M。
接下来 M 行每行两个正整数 a, b。 按 1~M 的顺序表示第 i 趟火车连接 a
和 b 两个省份。 保证 a 不等于 b,且同一对 a, b 只会出现一次。
[输出格式]
若干整数,从小到大排序,表示所有的可接受取消的火车序号。
[样例输入]
5 6
1 2
1 3
1 4
3 4
对于每一条可以删除的边,必然有下列特点:
1.有多条可以终点的路径,删除一条显然不影响。
2.这一条边不再最短路图上,在bfs的时候进行统计即可。
CODE
#include<bits/stdc++.h>
using namespace std;
int n,m;
vector<int>a[300000];
int q[10000000],h,t;
int vis[1000000];
int dis[1000000];
int x[300000],y[300000],in[300000];
inline void read(int &readnum)
{
int s=0;char c=getchar();
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9') s=s*10+c-48,c=getchar();
readnum=s;
}
int main()
{
freopen("train.in","r",stdin);
freopen("train.out","w",stdout);
cin>>n>>m;
for (int i=1;i<=m;++i)
{
read(x[i]),read(y[i]);
a[x[i]].push_back(y[i]);
a[y[i]].push_back(x[i]);
}
memset(in,0,sizeof(in));
memset(vis,0,sizeof(vis));
memset(dis,127,sizeof(dis));
vis[1]=1;dis[1]=0;h=t=1;q[1]=1;
for (;h<=t;++h)
{
int p=q[h];
for (int i=0;i<a[p].size();++i)
{
int np=a[p][i];
if (!vis[np])
{
q[++t]=np;
vis[np]=1;
dis[np]=dis[p]+1;
in[np]=1;
continue;
}
if (dis[p]+1==dis[np]) in[np]++;//统计到达一个点的路径总数
}
}
bool flag=false;
for (int i=1;i<=m;++i)
{
int c=x[i],d=y[i];
if (dis[c]>dis[d]) swap(c,d);//保证了c的深度小于d的深度
if (dis[d]-dis[c]!=1 || in[d]>1)//第一条件判断是否在最短路图上,第二个点判断是否可以存在多条相同的边
{
printf("%d\n",i);
flag=1;
}
}
if (!flag) printf("NO\n");
return 0;
fclose(stdin);
fclose(stdout);
return 0;
}