中南多校赛八

CSU2128 2130 2135 2136

A题 CSU2128

2128: Wells's Travel Plan

Submit Page      Summary      Time Limit: 3 Sec       Memory Limit: 128 Mb       Submitted: 39       Solved: 3    

Description

Wells来到了一个未知的梦幻国度,这个国度有 2N 个城市,分布为一个 2*N 的矩阵。有些城市是无法到达的。一个城市可以到达与之曼哈顿距离为 1 的城市。

大家都知道打acm没有太多的自由时间出去玩,但Wells仍然想知道,如果在从第 l 个城市出发到第 r 个城市的最少需要经过多少城市。

城市的分布如下图:

1, 2, 3, ....N

N+1,N+2,N+3....N*2

Input

第一行两个正整数 n,m,m 为询问数 接下来两行,每行是一个长度为 N 的字符串,表示城市能否经过。 若为 X,表示不能经过,若为 P,表示可以经过。 接下来 m 行,每行两个整数 l,r,描述一个询问。

Output

对于每个询问输出一行,l 到 r 的需要经过的最少城市个数(不包括起点,但包括终点),若无法到达输出-1。

Sample Input

3 4 
XPX
PPP
1 4
4 2
6 5 
6 4

Sample Output

-1
2
1
2

Hint

对于所有数据,n, m < =2 * 105.

扫描二维码关注公众号,回复: 2410339 查看本文章

 A题 本来应该是用倍增,但是暴力还是能卡极限过。。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <utility>
#include <stack>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <cmath>
#include <iostream>
#include <algorithm>
#define pi acos(-1.0)
#define e 2.718
#define lowbit(x) (x&(-x))
using  namespace std;
typedef unsigned long long  ull;
typedef long long ll;
const int N=4e5+9;
const long long mod=1e9+7;
const int maxn=2e5+25;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-8;

int n,m;
int mp[3][maxn];
char ch[maxn];
set<int> s[3];
int main() {
    while(~scanf("%d%d",&n,&m)&&n&&m) {
        scanf("%s",ch);
        s[0].clear();
        s[1].clear();
        for(int i=0; i<n; i++) {
            if(ch[i]=='X') {
                s[0].insert(i);
                mp[0][i]=-1;
            } else mp[0][i]=0;
        }
        scanf("%s",ch);
        for(int i=0; i<n; i++) {
            if(ch[i]=='X') {
                s[1].insert(i);
                mp[1][i]=-1;
            } else mp[1][i]=0;
        }
        for(int i=0; i<m; i++) {
            int a,b;
            int p=0,sum=0;
            scanf("%d%d",&a,&b);
            a--;
            b--;
            if(a%n>b%n)swap(a,b);
            int ka=a/n,va=a%n,kb=b/n,vb=b%n;
            if(mp[ka][va]==-1||mp[kb][vb]==-1)sum=-1;
            else {
                set<int>::iterator ite;
                ite=s[ka].upper_bound(va);
                if(ite!=s[ka].end())p=*ite;
                else p=INF;
                while(p<=vb) {
                    sum+=p-va;
                    ka=!ka;
                    va=p-1;
                    if(mp[ka][va]==-1) {
                        sum=-1;
                        break;
                    }
                    ite=s[ka].lower_bound(p);
                    if(ite!=s[ka].end())p=*ite;
                    else p=INF;
                    if(p-1==va) {
                        sum=-1;
                        break;
                    }
                }
                if(sum!=-1) {
                    sum+=vb-va;
                    if(kb!=ka)sum+=1;
                }
            }
            printf("%d\n",sum);
        }

    }
    return  0;
}


C 题 CSU 2130

C(2130):Permutations

Submit Page    Summary    Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 57     Solved: 20    


Description

给定两个1~n的排列A, B。每次可以把A的最后一个数取出,插入到A的任何一个位置(最前面或者任何两个数中间)。问最少几次可以把A转化为B

Input

第一行为一个整数n第二行为1~n的一个排列,表示A第三行为1~n的一个排列,表示B

Output

一个整数即最少操作次数。

Sample Input

5

1 5 2 3 4

1 2 3 4 5

Sample Output

3

Hint

30%:n <=100

50%:n <=1000

100%: n <= 200000

 最前面顺序正确的就是不用变换的,所以直接减去就行了。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <utility>
#include <stack>
#include <map>
#include <queue>
#include <vector>
#include <cmath>
#include <iostream>
#include <algorithm>
#define pi acos(-1.0)
#define e 2.718
#define lowbit(x) (x&(-x))
using  namespace std;
typedef unsigned long long  ull;
typedef long long ll;
const int N=4e5+9;
const long long mod=1e9+7;
const int maxn=1e7+25;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
int n;
int a[maxn],b[maxn];
map<int,int > m;
int main() {
    while(~scanf("%d",&n)) {
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        for(int i=0; i<n; i++) {
            scanf("%d",&b[i]);
            m[b[i]]=i;
        }
        int k=m[a[0]],ans=1;

        for(int i=1; i<n; i++) {
            if(m[a[i]]>k) {
                ans++;
                k=m[a[i]];
            } else break;
        }
        cout<<n-ans<<endl;
    }
    return  0;
}


H 题


H(2135):Appositive Body

SubmitPage    Summary    Time Limit: 10 Sec     Memory Limit: 512 Mb     Submitted: 29     Solved: 7    


Description

Yuki Nagato is an aliencreated by the Data Overmind, and possesses supernatural powers as a result.Two of her abilities are to observe the universe and to transcend time and space.

As we know, it is unstable ofthe universe if there are more than one active bodies which are actually thesame individual at the same time. Nagato defines them as appositivebodies. Of course, Nagato can tell whether there are any appositivebodies of one as soon as she observes.

Now, you become able totravel through time and space by some special chance. But before taking action,you have to make sure you won't destabilize the universe, so you can ask Nagatofor some help, including whether there is an appositive body of you at yourdestination. However, it is inconvenient to make a request every time, so youdecide to study this method.

At this time, you are able todescribe the universe abstractly, with several points in a 4-dimension vector,which are the space rectangular coordinates xy and z,and the time t. After filtered, these points seem to bein alignment. What you need to do now is to check whether these points arecentrosymmetric in four dimensional space. If they are, it means there is yourappositive body at your destination.

Input

Input consists of severaltest cases, for each test case:

First line: a integer n (1 ≤ n ≤ 107), the count ofpoints.

Next n lines:each line has four integers xyzt (−108 ≤ x, y, z, t ≤ 108), the coordinate of apoint.

Output

For each test case, output aline: if these points are centrosymmetric in four dimensional space, output"exist". Otherwise, output "not exist".

Sample Input

4
0 0 0 0
-1 0 3 4
4 8 2 2
5 8 -1 -2
3
0 0 0 0
1 1 1 1
1 1 1 1
4
0 0 0 0
1 1 1 1
1 1 1 1
0 0 0 0

Sample Output

exist
not exist
exist

 

排个序,然后 判断 第 I 个 加上 N-I-1个的xyzt,是不是全部等于2背平均数就行

暴力。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <utility>
#include <stack>
#include <map>
#include <queue>
#include <vector>
#include <cmath>
#include <iostream>
#include <algorithm>
#define pi acos(-1.0)
#define e 2.718
#define lowbit(x) (x&(-x))
using  namespace std;
typedef unsigned long long  ull;
typedef long long ll;
const int N=4e5+9;
const long long mod=1e9+7;
const int maxn=1e7+25;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
int n;
struct four {
    double x,y,z,t;
} f[maxn];

bool cmp(const four &a,const four &b) {
    if(a.t==b.t) {
        if(a.x==b.x) {
            if(a.y==b.y) {
                return a.z<b.z;
            } else return a.y<b.y;
        } else return a.x<b.x;
    } else return a.t<b.t;
}
long double cl(long double t)
{
    return t*2/n;
}

int main() {
    while(~scanf("%d",&n)) {
        long double x,y,z,t;
        x=y=z=t=0;
        for(int i=0; i<n; i++) {
            scanf("%lf%lf%lf%lf",&f[i].x,&f[i].y,&f[i].z,&f[i].t);
            x+=f[i].x;
            y+=f[i].y;
            z+=f[i].z;
            t+=f[i].t;
        }
        x=cl(x);
        y=cl(y);
        z=cl(z);
        t=cl(t);
//        cout<<x<<" "<<y<<" "<<z<<" "<<t<<endl;
        int flag=1;
        sort(f,f+n,cmp);
        for(int i=0; i<=(n-1)/2; i++) {
            if(abs(f[i].x+f[n-i-1].x-x)>eps||
               abs(f[i].y+f[n-i-1].y-y)>eps||
               abs(f[i].z+f[n-i-1].z-z)>eps||
               abs(f[i].t+f[n-i-1].t-t)>eps){
                   flag=0;
               }
        }
        puts(flag?"exist":"not exist");
    }
    return  0;
}


I

I(2136):统帅三军!

Submit Page    Summary    Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 7     Solved: 1    


Description

Wells最近迷上了一款攻城的策略游戏,点就去就能当大元帅统帅三军!

游戏界面主要是一个平面(坐标可以为浮点数),然而Wells发现这游戏是个骗局,其实只给了一个军队。

Wells初始有一个军队,仅包含n个士兵,每个士兵有一个初始位置(x,y)和一个劳累指数Wi,每个队员可以移动,显然对于每个队员的移动是需要消耗一些体力的,若第i个队员从位置(x1,y1)移动到(x2,y2)的体力消耗为Wi*(|x2-x1|+|y2-y1|)

Wells希望先将队伍集合起来,且希望整个队伍一次集合的体力消耗越少越好。显然能量消耗的多少直接取决与Wells对于会和点(x,y)的选择,然而Wells太懒了,希望你帮他找出某个时刻的最佳会和点。

Input

对于每组数据:

第一行:一个整数N,表示士兵数目。

第二行:一共N个整数,其中的第i个数Wi表示第i个队员的劳累指数。(N<=106)(N<=106)

接下来N行:每一行两个整数XY,表示第i个士兵的当前的横坐标和纵坐标。(−109<=X,Y<=109)(−109<=X,Y<=109)

Output

一个实数。表示所有队员集合到最佳攻击位置的体力消耗总和,答案保留两位小数。

Sample Input

1

1

0 0

Sample Output

0.00

I

这题比较毒瘤,写了半天三分发现精度有问题,后来仔细想了下,根本不可能是小数,

他求的是曼哈顿距离,可以把X,Y分开算。

从左往右走到某个点 左边的W > 右边W的和就可以了,那个时候绝对就是临界值

因为再往左走一定是增的比减的少

Y轴也是同理

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <utility>
#include <stack>
#include <map>
#include <queue>
#include <vector>
#include <cmath>
#include <iostream>
#include <algorithm>
#define pi acos(-1.0)
#define e 2.718
#define lowbit(x) (x&(-x))
using  namespace std;
typedef unsigned long long  ull;
typedef long long ll;
const int N=4e5+9;
const long long mod=1e9+7;
const int maxn=1e7+25;
const int INF=0x7fffffff;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
int n;
struct P{
    int x,w,y;
}p[maxn];
bool cmp(const P & a,const P & b)
{
    return a.x<b.x;
}
bool cmp2(const P &a,const P & b)
{
    return a.y<b.y;
}

long long jsx(int l)
{
    long long s1=0,s2=0;
    for(int i=0;i<n;i++)
    {
        s1+=abs(p[i].w*(p[i].x-p[l].x));
    }
    for(int i=0;i<n;i++)
    {
        s2+=abs(p[i].w*(p[i].x-p[l-1].x));
    }
    return min(s1,s2);
}
long long jsy(int l)
{
    long long s1=0,s2=0;
    for(int i=0;i<n;i++)
    {
        s1+=abs(p[i].w*(p[i].y-p[l].y));
    }
    for(int i=0;i<n;i++)
    {
        s2+=abs(p[i].w*(p[i].y-p[l-1].y));
    }
    return min(s1,s2);
}

int main() {
    while(~scanf("%d",&n)) {
        for(int i=0;i<n;i++)
        scanf("%d",&p[i].w);
        long long aw=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y);
            aw+=p[i].w;
        }
        sort(p,p+n,cmp);
        long long l=0,r=aw-p[0].w,sum=0;
        for(int i=1;i<n;i++)
        {
            l+=p[i-1].w;
            r-=p[i].w;
            if(r<=l)
            {
                sum+=jsx(i);
                break;
            }
        }
        sort(p,p+n,cmp2);
        l=0;r=aw-p[0].w;
        for(int i=1;i<n;i++)
        {
            l+=p[i-1].w;
            r-=p[i].w;
            if(r<=l)
            {
                sum+=jsy(i);
                break;
            }
        }
        printf("%lld.00\n",sum);
    }
    return  0;
}

猜你喜欢

转载自blog.csdn.net/qq_40871466/article/details/80599711
今日推荐