1.足球联赛
(soccer.pas/c/cpp)
【问题描述】
巴蜀中学新一季的足球联赛开幕了。足球联赛有 n 只球队参赛,每赛季,每只球队要与
其他球队各赛两场,主客各一场,赢一场得 3 分,输一场不得分,平局两只队伍各得一分。
英勇无畏的小鸿是机房的主力前锋,她总能在关键时刻踢出一些匪夷所思的妙球。但是
很可惜,她过早的燃烧完了她的职业生涯,不过作为一个能够 Burning 的 girl,她的能力不
止如此,她还能预测这个赛季所有球队的比赛结果。
虽然她能准确预测所有比赛的结果,但是其实她不怎么厉害,Mr.Gao 上数学课时她总
是在 sleep,因此她的脑里只有整数没有实数,而且,她只会 10 以内非负整数的加法运算,
因此她只有结果却无法知道谁会获得联赛的冠军。
小鸿想给冠军队伍的所有队员一个拥抱,所以她把计算结果的任务交给了你:
现在,给你一个 n*n 的矩阵表示比赛情况。第 i 行第 j 列的字母表示在第 i 只队伍
在主场迎战第 j 只队伍的比赛情况,W 表示主队赢,L 表示主队输,D 表示平局。现在需
要你给出最后能得到小鸿拥抱的队伍编号,如有多支队伍分数最高,按字典序输出编号。
【输入格式】
第一行一个整数 n。
接下来 n 行,每行 n 个字符,表示输赢情况。
第 i 行第 i 列为 - ,因为一只队伍不可能与自己比赛。
【输出格式】
输出得分最高的队伍编号。如有多个在一行中输出,用一个空格分开。
【样例输入输出 1】
3
-WW
W-W
WW
【输出】
1 2 3
【样例输入输出 2】
5
-DWWD
L-WLL
DD-WD
DDL-L
DDLL
【输出】
1
数据范围】
对于 40%的数据,满足 N<=20
对于 100%的数据,满足 N<=50
#include<iostream>
#define inc(i,l,r) for(int i=l;i<=r;++i)
using namespace std;
int ans[55],n;
char s[55];
int main()
{
scanf("%d",&n);
inc(i,1,n)
{
scanf("%s",s+1);
inc(j,1,n)
{
if(s[j]=='L')ans[j]+=3;
else if(s[j]=='W')ans[i]+=3;
else if(s[j]=='D'){++ans[i];++ans[j];}
}
}
int maxx=0;
inc(i,1,n)
maxx=max(maxx,ans[i]);
inc(i,1,n)
if(ans[i]==maxx)printf("%d ",i);
return 0;
}
2.最短路径
(paths.pas/c/cpp)
【问题描述】
平面内给出 n 个点,记横坐标最小的点为 A,最大的点为 B,现在小 Y 想要知道在
每个点经过一次(A 点两次)的情况下从 A 走到 B,再回到 A 的最短路径。但他是个强
迫症患者,他有许多奇奇怪怪的要求与限制条件:
1.从 A 走到 B 时,只能由横坐标小的点走到大的点。
2.由 B 回到 A 时,只能由横坐标大的点走到小的点。
3.有两个特殊点 b1 和 b2, b1 在 0 到 n-1 的路上,b2 在 n-1 到 0 的路上。
请你帮他解决这个问题助他治疗吧!
【输入格式】
第一行三个整数 n,b1,b2,( 0 < b1,b2 < n-1 且 b1 <> b2)。n 表示点数,从 0 到 n-1 编
号,b1 和 b2 为两个特殊点的编号。
以下 n 行,每行两个整数 x、y 表示该点的坐标(0 <= x,y <= 2000),从 0 号点顺序
给出。Doctor Gao 为了方便他的治疗,已经将给出的点按 x 增序排好了。
【输出格式】
输出仅一行,即最短路径长度(精确到小数点后面 2 位)
【样例输入】
5 1 3
1 3
3 4
4 1
7 5
8 3
【输出】
18.18
【样例解释】
最短路径:0->1->4->3->2->0
【数据范围】
20%的数据 n<=20
60%的数据 n<=300
100%的数据 n<=1000
对于所有数据 x,y,b1,b2 如题目描述
#include<bits/stdc++.h>
#define re return
#define D double
#define inc(i,l,r) for(register int i=l;i<=r;++i)
int maxn=200005;
using namespace std;
template<typename T>inline void rd(T&x)
{
char c;bool f=0;
while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
x=c^48;
while((c=getchar())>='0'&c<='9')x=x*10+(c^48);
if(f)x=-x;
}
double f[1005][1005],dis[1005][1005];
int n,o,p;
struct node{
int x,y;
}pos[1005];
D cala(int x,int y)
{
re x*x+y*y;
}
int main()
{
//freopen("paths.in","r",stdin);
//freopen("paths.out","w",stdout);
rd(n);rd(o);rd(p);++o;++p;
inc(i,1,n)rd(pos[i].x),rd(pos[i].y);
inc(i,1,n)
{
f[i][i]=100000000;
inc(j,i+1,n)
{
dis[i][j]=sqrt(cala(pos[i].x-pos[j].x,pos[i].y-pos[j].y));
f[i][j]=f[j][i]=100000000;
}
}
f[1][1]=0;
inc(k,1,n)
{
if(p!=k&&o!=k)
{
inc(i,1,k-1)
{
f[k-1][k]=min(f[k-1][k],dis[i][k]+f[k-1][i]);
f[i][k]=min(f[i][k],f[i][k-1]+dis[k-1][k]);
f[k][k-1]=min(f[k][k-1],dis[i][k]+f[i][k-1]);
f[k][i]=min(f[k][i],f[k-1][i]+dis[k-1][k]);
}
}
else if(k==p)
{
inc(i,1,k-1)
{
f[k-1][k]=min(f[k-1][k],dis[i][k]+f[k-1][i]);
f[i][k]=min(f[i][k],f[i][k-1]+dis[k-1][k]);
}
}
else {
inc(i,1,k-1)
{
f[k][k-1]=min(f[k][k-1],dis[i][k]+f[i][k-1]);
f[k][i]=min(f[k][i],f[k-1][i]+dis[k-1][k]);
}
}
}
D ans=105555555554;
inc(i,1,n-1)
{
ans=min(ans,f[i][n]+dis[i][n]);
ans=min(ans,f[n][i]+dis[i][n]);
}
printf("%.2lf",ans);
re 0;
}
3.阿 Q 的停车场
(park.pas/c/cpp)
【问题描述】
刚拿到驾照的 KJ 总喜欢开着车到处兜风,玩完了再把车停到阿 Q 的停车场里,虽然
她对自己停车的水平很有信心,但她还是不放心其他人的停车水平,尤其是 Kelukin。于是,
她每次都把自己的爱车停在距离其它车最远的一个车位。KJ 觉得自己这样的策略非常科
学,于是她开始想:在一个停车场中有一排车位,从左到右编号为 1 到 n,初始时全部是
空的。有若干汽车,进出停车场共 m 次。对于每辆进入停车场的汽车,会选择与其它车距
离最小值最大的一个车位,若有多个符合条件,选择最左边一个。KJ 想着想着就睡着了,
在她一旁的 Kelukin 想帮她完成这个心愿,但是他又非常的懒,不愿意自己动手,于是就把
这个问题就留给了你:在 KJ 理想的阿 Q 的停车场中,给你车辆进出的操作序列,依次输
出每辆车的车位编号。
【输入说明】
第一行,两个整数 n 和 m,表示停车场大小和操作数;
接下来 m 行,每行两个整数 F 和 x
F 是 1 表示编号为 x 的车进停车场;
F 是 2 表示编号为 x 的车出停车场;
保证操作合法,即:
出停车场的车一定目前仍在停车场里;
停车场内的车不会超过 n;
【输出说明】
于所有操作 1,输出一个整数,表示该车车位的编号。
【样例输入】
7 11
1 15
1 123123
1 3
1 5
2 123123
2 15
1 21
2 3
1 6
1 7
1 8
输出
1
7
4
2
7
4
1
3
【数据范围】
对 30%的数据 n<=1000 ,m<=1000
对 60%的数据 n<=200000,m<=2000
对 100%的数据 n,m<=200000,车的编号小于等于 10^6
详见大佬思路
不过貌似代码用一点点小错误,
特此献上我的诡奇代码
#include<bits/stdc++.h>
#define re return
#define lson rt<<1
#define rson rt<<1|1
#define inc(i,l,r) for(int i=l;i<=r;++i)
const int maxn=200003;
using namespace std;
template<typename T>inline void rd(T&x)
{
char c;bool f=0;
while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
x=c^48;
while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
if(f)x=-x;
}
int n,m,opt,hide[10000005];
struct node{
int x,y,mid,p;
}t[maxn<<2];
inline void update(int rt)
{
t[rt].x=t[lson].x;
if(!t[rt].x)t[rt].x=t[rson].x;
t[rt].y=t[rson].y;
if(!t[rt].y)t[rt].y=t[lson].y;
t[rt].mid=t[lson].mid;t[rt].p=t[lson].p;
if(t[rt].mid<t[rson].mid){
t[rt].mid=t[rson].mid;t[rt].p=t[rson].p;
}
if(t[rson].x&&t[lson].y&&((t[rson].x-t[lson].y)/2>t[rt].mid)||((t[rson].x-t[lson].y)/2==t[rt].mid&&((t[lson].y+t[rson].x)/2<t[rt].p)))
{
//小细节2:判断相等情况,优先选左
t[rt].mid=(t[rson].x-t[lson].y)/2;
t[rt].p=(t[lson].y+t[rson].x)/2;
}
}
void add(int rt,int l,int r,int pos,int f)
{
if(l==r)
{
if(f)
{
t[rt].x=t[rt].y=l;
t[rt].mid=t[rt].p=0;
}
else
{
t[rt].x=t[rt].y=0;
t[rt].mid=1;t[rt].p=l;
}
re ;
}
int mid=(l+r)>>1;
if(mid<pos)add(rson,mid+1,r,pos,f);
else add(lson,l,mid,pos,f);
update(rt);
}
int tot,visx,visn;
int main()
{
int x;
rd(n),rd(m);
inc(i,1,m)
{
rd(opt),rd(x);
if(opt==1)
{
if(!t[1].x||(!visx&&(t[1].x-1>=t[1].mid))){hide[x]=1;visx=1;}
else if(!visn&&n-t[1].y>t[1].mid){hide[x]=n;visn=1;}
//小细节1:判断1,n位置是否该放,做好标记
else hide[x]=t[1].p;
add(1,1,n,hide[x],1);
printf("%d\n",hide[x]);
}
else {
add(1,1,n,hide[x],0);
if(hide[x]==1)visx=0;
else if(hide[x]==n)visn=0;
}
}
re 0;
}