Day 1

来源:互联网 发布:苹果手机怎么信任软件 编辑:程序博客网 时间:2024/05/29 07:48

1.转圈游戏

(circle.cpp/c/pas)

【问题描述】

n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏。按照顺时针方向给 n 个位置编号,从

0 到 n-1。最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此类推。

游戏规则如下:每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,……,依此类推,第n − m号位置上的小伙伴走到第 0 号位置,第 n-m+1 号位置上的小伙伴走到第 1 号位置,……,第 n-1 号位置上的小伙伴顺时针走到第 m-1 号位置。

现在,一共进行了 10^k 轮,请问 x 号小伙伴最后走到了第几号位置。

【输入】
输入文件名为 circle.in。
输入共 1 行,包含 4 个整数 n、m、k、x,每两个整数之间用一个空格隔开。

【输出】
输出文件名为 circle.out。
输出共 1 行,包含 1 个整数,表示 10k 轮后 x 号小伙伴所在的位置编号。

【输入样例】
10 3 4 5

【输出样例】
5

【数据说明】
对于 30%的数据,0 ≤k<≤6;
对于 80%的数据,0 ≤k≤ 10^7;
对于 100%的数据,1 ≤n<≤1,000,000,0 ≤m≤n ,1 ≤ x ≤ n,0 ≤k≤ 10^9。

思路:用到快速幂优化,背诵内容

#include<cstdio>typedef long long LL;using namespace std;int n,m,k,x;LL fuc(int p,int k){    LL temp=p,s=1;    while(k!=0){        if(k&1) s=(s*(temp%n))%n;        temp=(temp*temp)%n;        k>>=1;    }    return s;}int main(){//  freopen("circle.in","r",stdin);//  freopen("circle.out","w",stdout);    scanf("%d%d%d%d",&n,&m,&k,&x);    printf("%I64d",(m*fuc(10,k)+x)%n);    return 0;}//printf %I64d 去掉 LL去掉 则无错误 

火柴排队

(match.cpp/c/pas)

【问题描述】

涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:Σni=(ai−bi)2,其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。

每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最

小交换次数对 99,999,997 取模的结果。

【输入】输入文件为 match.in。

共三行,第一行包含一个整数 n,表示每盒中火柴的数目。

第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

【输出】输出文件为 match.out。

输出共一行,包含一个整数,表示最少交换次数对 99,999,997 取模的结果。

【输入输出样例 1】

4 1
2 3 1 4
3 2 1 4

【输入输出样例说明】

最小距离是 0,最少需要交换 1 次,比如:交换第 1 列的前 2 根火柴或者交换第 2 列的前 2 根火柴。

【输入输出样例 2】

4 2
1 3 4 2
1 7 2 4

【输入输出样例说明】

最小距离是 10,最少需要交换 2 次,比如:交换第 1 列的中间 2 根火柴的位置,再交换第 2 列中后 2 根火柴的位置。

【数据范围】
对于 10%的数据, 1 ≤ n ≤10;
对于 30%的数据,1 ≤ n ≤ 100;
对于 60%的数据,1 ≤ n ≤ 1,000;

思路:a序列里第几大的要对上b序列里第几大的,可用结构体使a、b序列重新对齐

//逆序对 归并排序 //大对大,小对小 #include <cstring>#include <cstdio>#include <algorithm>using namespace std;int a[100010],b[100010],temp[100010],aa[100010],bb[100010];void qs(int *x,int *y,int l,int r){    int i=l,j=r,m=x[(l+r)>>1];    while(i<=j){        while(x[i]<m)i++;        while(x[j]>m)j--;        if(i<=j){            swap(x[i],x[j]);            swap(y[i++],y[j--]);        }    }    if(i<r) qs(x,y,i,r);    if(j>l) qs(x,y,l,j);}long long merge(int *a,int l,int m,int r,int *b){    int i=l,k=l,j=m+1;    long long sum=0;    memcpy(b+l,a+l,sizeof(int)*(r-l+1));    while(i<=m&&j<=r){        if(b[i]<=b[j])        a[k++]=b[i++];        else{            a[k++]=b[j++];            sum+=(m-i+1);            sum%=99999997;        }    }    while(i<=m) a[k++]=b[i++];    while(j<=r) a[k++]=b[j++];    return sum;}long long merge_sort(int *a,int l,int r,int *b){    long long sum=0;    if(l<r){        int m=(l+r)>>1;        sum+=merge_sort(a,l,m,b);        sum+=merge_sort(a,m+1,r,b);        sum+=merge(a,l,m,r,b);        sum%=99999997;    }    return sum;}int main(){    freopen("match.in","r",stdin);    freopen("match.out","w",stdout);    int n,i;    long long sum;    scanf("%d",&n);    for(i=1;i<=n;i++)        scanf("%d",&a[i]),        aa[i]=i;    for(i=1;i<=n;i++)        scanf("%d",&b[i]),        bb[i]=i;    qs(a,aa,1,n);    qs(b,bb,1,n);    for(i=1;i<=n;i++)        b[aa[i]]=bb[i];    sum=merge_sort(b,1,n,temp);    printf("%lld",sum);    return 0;}

或者

//树状数组 #include<cstdio>#include<algorithm>#include<iostream> using namespace std;const int siz=100010,mod=99999997;int n,ans;int an[siz],c[siz]; struct node{int v,i;} a[siz],b[siz];bool cmp(const node &c,const node &d){return c.v<d.v;}int lowbit(int x){return x&(-x);}void add(int x,int y){for(;x<=n;x+=lowbit(x)) c[x]+=y;}//加上去 int get(int x){int res=0;for(;x;x-=lowbit(x)) res+=c[x];return res;}//求前缀和 int main(){    ans=0;     scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d",&a[i].v),a[i].i=i;    for(int i=1;i<=n;i++)        scanf("%d",&b[i].v),b[i].i=i;    sort(a+1,a+1+n,cmp);sort(b+1,b+1+n,cmp);    for(int i=1;i<=n;i++)        an[a[i].i]=b[i].i; //把b里的顺序按照a里的改了 a[i]第几个 a[i].i这个位置的数的大小排位     for(int i=n;i>=1;i--){        ans+=get(an[i]-1);         ans%=mod;         add(an[i],1);    }    cout<<ans<<endl;    return 0;   }

货车运输

(truck.cpp/c/pas)

【问题描述】

A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

【输入】输入文件名为 truck.in。

输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道

路。

接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。

接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。

【输出】输出文件名为 truck.out。

输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。

【输入样例】

4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3

【输出样例】
3
-1
3

【数据说明】

对于 30%的数据,0 ≤n≤1,000,0 ≤m≤ 10,000,0≤q≤1,000;对于 60%的数据,0 ≤n≤1,000,0 ≤m≤50,000,0 ≤q≤ 1,000;

对于 100%的数据,0 ≤n≤10,000,0 ≤m≤50,000,0 ≤q≤30,000,0 ≤ z ≤ 100,000。

思路:最大生成树+LCA.

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;vector <int> ans1[10010];int m,n,q;int father[10010],s[30010],t[30010];int ans[30010];bool vist[30010];struct node{    int x,y,z;}a[51000];int getfa(int x)//找爹 {    if(father[x]==x) return x;    return father[x]=getfa(father[x]);}bool jianb(int x,int y)//建边 {    int a=getfa(x),b=getfa(y);    if(a!=b)    {        father[b]=a;        return false;    }    return true;}int cmp(node xx,node yy)//根据边权的大小排序 {    return xx.z>yy.z;}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        father[i]=i;    for(int i=1;i<=m;i++)        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);    sort(a+1,a+m+1,cmp);    scanf("%d",&q);    for(int i=1;i<=q;i++)        scanf("%d%d",&s[i],&t[i]);    for(int i=1;i<=m;i++)    {        if(getfa(a[i].x)!=getfa(a[i].y))            jianb(a[i].x,a[i].y);        if(i==m || i%100==0)        {            for(int j=1;j<=q;j++)                if(vist[j]==0 && getfa(s[j])==getfa(t[j]))                    vist[j]=1,                    ans1[(i-1)/100].push_back(j);        }    }    for(int i=1;i<=n;i++)        father[i]=i;    memset(ans,-1,sizeof(ans));//如果无法求解,则输出-1     for(int i=1;i<=m;i++)    {        if(getfa(a[i].x)!=getfa(a[i].y))//若无连接,则连起来            jianb(a[i].x,a[i].y);        int num=(i-1)/100;        for(int j=0;j<ans1[num].size();j++)        {            if(ans[ans1[num][j]]==-1&&getfa(s[ans1[num][j]])==getfa(t[ans1[num][j]]))                ans[ans1[num][j]]=a[i].z;        }    }    for(int i=1;i<=q;i++)        printf("%d\n",ans[i]);    return 0;} 

这里有大神的详注

1 0
原创粉丝点击