zoukankan      html  css  js  c++  java
  • 江理oj 摸底测试 解题报告

             http://oj.jxust.edu.cn/contest?id=1702

    A  :::

    思路::开一个数组暂时记录一下每个杯子加的水量(假设无穷大);再遍历一便数组如果大于当前杯子的容量,则将多余的水量移至下一水杯

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=1e5+5;
     5 
     6 ll a[maxn],b[maxn];
     7 int n,m;
     8 int main()
     9 {
    10     int t;
    11     scanf("%d",&t);
    12     while(t--){
    13         //memset(b,0,sizeof(b));
    14         scanf("%d%d",&n,&m);
    15         for(int i=1;i<=n;i++){
    16             scanf("%lld",&a[i]);
    17             b[i]=0;
    18         }
    19         while(m--){
    20             int x;
    21             ll y;
    22             scanf("%d%lld",&x,&y);
    23             b[x]+=y;
    24         }
    25         ll jw=0;
    26         for(int i=1;i<=n;i++){
    27             if(b[i]+jw>a[i]){
    28                 jw=b[i]+jw-a[i];
    29                 b[i]=a[i];
    30             }
    31             else if(b[i]+jw<a[i]){
    32                 b[i]=b[i]+jw;jw=0;
    33             }
    34             else if(b[i]+jw==a[i]){
    35                 b[i]=a[i];jw=0;
    36             }
    37         }
    38         for(int i=1;i<=n;i++){
    39             if(i==1){printf("%lld",b[i]);}
    40             else{printf(" %lld",b[i]);
    41             }
    42         }
    43         printf("
    ");
    44     }
    45     return 0;
    46 }
    View Code

    B :::

    思路:: 预处理:线性筛素数       枚举两个素数,再判断第三个数是否为素数(三个素数的关系   第一个素数 <= 第二个素数  <= 第三个素数 )避免重复计数

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=4e4+5;
     5 const int Maxn=1e8;
     6 
     7 bool isprime[maxn];
     8 int prime[maxn];
     9 int num_prime=0;
    10 void get_prime()
    11 {
    12     isprime[0]=1;
    13     isprime[1]=1;
    14     for(int i=2;i<=maxn;i++){
    15         if(!isprime[i]){
    16             prime[num_prime++]=i;
    17         }
    18         for(int j=0;j<num_prime&&i*prime[j]<=maxn;j++){
    19             isprime[i*prime[j]]=1;
    20             if(i%prime[j]==0){break;}
    21         }
    22     }
    23 }
    24 int main()
    25 {
    26     get_prime();
    27     int t;
    28     scanf("%d",&t);
    29     while(t--){
    30         int n;
    31         scanf("%d",&n);
    32         if(n<=5){
    33             printf("0
    ");continue;
    34         }
    35         int sum=0;
    36         for(int i=0;prime[i]<=n;i++){
    37             for(int j=i;prime[j]+prime[i]<=n;j++){
    38                 if(isprime[n-prime[i]-prime[j]]==0&&(n-prime[i]-prime[j])>=prime[j]){sum++;}
    39             }
    40         }
    41         cout<<sum<<endl;
    42     }
    43     return 0;
    44 }
    View Code

    C :::

    思路::分别对 x y z 排序,再对全部建立的边排序,再跑一下克鲁斯卡尔即可;

    由题意可以知当你在某两点之间建立边时,你只会用 X,Y,Z 中的一种建立,而对X排序的话保证了相邻的两点建边花费最小(必然不会选择与其他点建立)所以只需建立n-1条边,对Y,Z同样的道理,跑克鲁斯卡尔

     1 //#include<bits/stdc++.h>
     2 #include<iostream>
     3 #include<stdio.h>
     4 #include<string>
     5 #include<string.h>
     6 #include<algorithm>
     7 #include<stack>
     8 #include<set>
     9 #include<map>
    10 #define ll long long
    11 using namespace std;
    12 const int maxn=2e5+5;
    13 const int inf=1e9+7;
    14 
    15 struct node
    16 {
    17     int x,y,z,pos,val;
    18 }a[maxn],b[maxn*3];
    19 int f[maxn];
    20 bool cmp1(node A,node B)
    21 {
    22     return A.x<B.x;
    23 }
    24 bool cmp2(node A,node B)
    25 {
    26     return A.y<B.y;
    27 }
    28 bool cmp3(node A,node B)
    29 {
    30     return A.z<B.z;
    31 }
    32 bool cmp4(node A,node B)
    33 {
    34     return A.val<B.val;
    35 }
    36 int getfind(int x)
    37 {
    38     return f[x]==x?x:f[x]=getfind(f[x]);
    39 }
    40 int main()
    41 {
    42     int n;
    43     scanf("%d",&n);
    44     for(int i=1;i<=n;i++){
    45         scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    46         a[i].pos=i;
    47         f[i]=i;
    48     }
    49     int ant=0;
    50     sort(a+1,a+n+1,cmp1);
    51     for(int i=1;i<n;i++){
    52         b[++ant].x=a[i].pos;
    53         b[ant].y=a[i+1].pos;
    54         b[ant].val=abs(a[i].x-a[i+1].x);
    55     }
    56     sort(a+1,a+n+1,cmp2);
    57     for(int i=1;i<n;i++){
    58         b[++ant].x=a[i].pos;
    59         b[ant].y=a[i+1].pos;
    60         b[ant].val=abs(a[i].y-a[i+1].y);
    61     }
    62     sort(a+1,a+n+1,cmp3);
    63     for(int i=1;i<n;i++){
    64         b[++ant].x=a[i].pos;
    65         b[ant].y=a[i+1].pos;
    66         b[ant].val=abs(a[i].z-a[i+1].z);
    67     }
    68     sort(b+1,b+ant+1,cmp4);
    69     int cnt=1,sum=0;
    70     for(int i=1;i<=ant;i++){
    71         int t1=getfind(b[i].x);
    72         int t2=getfind(b[i].y);
    73         if(t1!=t2){
    74             f[t2]=t1;
    75             cnt++;
    76             sum+=b[i].val;
    77         }
    78         if(cnt>=n){break;}
    79     }
    80     cout<<sum<<endl;
    81     return 0;
    82 }
    View Code

    D :::

    思路::

    E :::

    思路::预处理前dp[i](1<=i<=5)   转态转移方程 dp[i]=max(dp[j]*dp[i-j])(j=1,2~i/2);再就是求逆元,

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=4e4+5;
     5 const int Maxn=1e8;
     6 
     7 ll a[105];
     8 ll exgcd(ll a,ll b,ll &x,ll &y)
     9 {
    10     if(b==0){
    11         x=1;
    12         y=0;
    13         return a;
    14     }
    15     int r=exgcd(b,a%b,x,y);
    16     int t=x;
    17     x=y;
    18     y=t-a/b*y;
    19     return t;
    20 }
    21 int main()
    22 {
    23     ll n;
    24     scanf("%lld",&n);
    25     a[1]=1,a[2]=2,a[3]=3,a[4]=4;
    26     for(ll i=5;i<=n;i++){
    27         ll ans=0;
    28         for(ll j=1;j<=i/2;j++){
    29             ans=max(ans,a[j]*a[i-j]);
    30         }
    31         a[i]=ans;
    32     }
    33     ll x,y;
    34     exgcd(n,a[n],x,y);
    35     printf("%lld
    ",(x+a[n])%a[n]);
    36     return 0;
    37 }
    View Code

    F :::

    思路::线段树区间更新,只需对lazy标记处理,只有 lazy值为奇数时反转,

     1 //#include <bits/stdc++.h>
     2 #include<string.h>
     3 #include<stdio.h>
     4 #include<iostream>
     5 #include<string>
     6 #include<algorithm>
     7 #define ll long long
     8 using namespace std;
     9 
    10 const int maxn=1e5+5;
    11 int lazy[maxn<<2];
    12 
    13 void build(int l,int r,int rt)
    14 {
    15     lazy[rt]=0;
    16     if(l==r){
    17         return ;
    18     }
    19     int mid=(l+r)>>1;
    20     build(l,mid,2*rt);
    21     build(mid+1,r,2*rt+1);
    22 }
    23 void pushup(int rt)
    24 {
    25     if(lazy[rt]!=0){
    26         if(lazy[rt]%2==0){lazy[rt]=0;return ;}
    27         lazy[2*rt]+=lazy[rt];
    28         lazy[2*rt+1]+=lazy[rt];
    29         lazy[rt]=0;
    30     }
    31 }
    32 void update(int L,int R,int l,int r,int rt)
    33 {
    34     if(L<=l&&R>=r){
    35         lazy[rt]++;
    36         return ;
    37     }
    38     pushup(rt);
    39     int mid=(l+r)>>1;
    40     if(L<=mid){
    41         update(L,R,l,mid,2*rt);
    42     }
    43     if(mid<R){
    44         update(L,R,mid+1,r,2*rt+1);
    45     }
    46 }
    47 int query(int tr,int l,int r,int rt)
    48 {
    49     if(l==r){
    50         if(lazy[rt]&1){
    51             return 1;
    52         }
    53         else{
    54             return 0;
    55         }
    56     }
    57     pushup(rt);
    58     int mid=(l+r)>>1;
    59     if(tr<=mid){
    60         query(tr,l,mid,2*rt);
    61     }
    62     else{
    63         query(tr,mid+1,r,2*rt+1);
    64     }
    65 }
    66 int main()
    67 {
    68     int n,m;
    69     scanf("%d%d",&n,&m);
    70     build(1,n,1);
    71     while(m--)
    72     {
    73       int op,a,b;
    74       scanf("%d",&op);
    75       if(op==1){
    76         scanf("%d%d",&a,&b);
    77         update(a,b,1,n,1);
    78       }
    79       else{
    80         scanf("%d",&a);
    81         printf("%d
    ",query(a,1,n,1));
    82       }
    83     }
    84     return 0;
    85 }
    View Code

    G :::

    思路:: 最少派2个人去,最多派n个人去,对于每个去的人来讲有两种选择(送或接礼物)但要除去全接和全收礼物的情况

    阶乘逆元模板

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=1e5+5;
     5 const ll MOD=1e9+7;
     6 
     7 ll fa[maxn],inv[maxn];
     8 ll qpow(ll x,ll p)
     9 {
    10     ll ans=1;
    11     while(p){
    12         if(p&1){
    13             ans=(ans*x)%MOD;
    14         }
    15         x=(x*x)%MOD;
    16         p>>=1;
    17     }
    18     return ans;
    19 }
    20 void pre()
    21 {
    22     fa[0]=1;
    23     for(int i=1;i<=maxn;i++){
    24         fa[i]=(fa[i-1]*i)%MOD;
    25     }
    26     inv[maxn]=qpow(fa[maxn],MOD-2);
    27     for(int i=maxn-1;i>=0;i--){
    28         inv[i]=inv[i+1]*(i+1)%MOD;
    29     }
    30 }
    31 int main()
    32 {
    33     pre();
    34     int n;
    35     scanf("%d",&n);
    36     if(n==1){
    37         printf("0
    ");return 0;
    38     }
    39     ll sum=0;
    40     for(int i=2;i<=n;i++){
    41         sum=(sum+fa[n]*inv[i]%MOD*inv[n-i]%MOD*(qpow(2,i)-2)%MOD)%MOD;
    42     }
    43     printf("%lld
    ",sum);
    44     return 0;
    45 }
    View Code

     H :::

    思路::跑三遍最短路,第一,第二遍判断他们之间是否存在相同的能到达终点的最短路,存在则再将两地图为合并(两者都为 " * " 时才为 ” * ” ,反之 “ # ” ),第三遍跑合并地图判断最短路是否为之前的最短路相等

      1 #include<bits/stdc++.h>
      2 #define ll long long
      3 using namespace std;
      4 const int maxn=505;
      5 const int inf=1e9+7;
      6 
      7 char mp1[maxn][maxn],mp2[maxn][maxn];
      8 int n,m;
      9 struct node
     10 {
     11     int x,y,step;
     12     node(){}
     13     node(int _x,int _y,int _step):x(_x),y(_y),step(_step){}
     14 
     15 };
     16 int fx[]={0,0,1,-1};
     17 int fy[]={1,-1,0,0};
     18 bool vis[maxn][maxn];
     19 int s1=1e9,s2=1e9;
     20 
     21 void bfs1()
     22 {
     23     memset(vis,0,sizeof(vis));
     24     queue<node>q;
     25     node t,p;
     26     q.push(node(1,1,0));
     27     vis[1][1]=1;
     28     while(!q.empty())
     29     {
     30         t=q.front();
     31         q.pop();
     32         if(t.x==n&&t.y==m){
     33             s1=t.step;return ;
     34         }
     35         for(int i=0;i<4;i++){
     36             p.x=t.x+fx[i];
     37             p.y=t.y+fy[i];
     38             if(p.x>=1&&p.x<=n&&p.y>=1&&p.y<=m&&mp1[p.x][p.y]!='#'&&vis[p.x][p.y]==0){
     39                 p.step=t.step+1;
     40                 vis[p.x][p.y]=1;
     41                 if(p.x==n&&p.y==m){
     42                     s1=p.step;return ;
     43                 }
     44                 q.push(node(p.x,p.y,p.step));
     45             }
     46         }
     47     }
     48 }
     49 void bfs2()
     50 {
     51     memset(vis,0,sizeof(vis));
     52     queue<node>q;
     53     node t,p;
     54     q.push(node(1,1,0));
     55     vis[1][1]=1;
     56     while(!q.empty())
     57     {
     58         t=q.front();
     59         q.pop();
     60         if(t.x==n&&t.y==m){
     61             s2=t.step;return ;
     62         }
     63         for(int i=0;i<4;i++){
     64             p.x=t.x+fx[i];
     65             p.y=t.y+fy[i];
     66             if(p.x>=1&&p.x<=n&&p.y>=1&&p.y<=m&&mp2[p.x][p.y]!='#'&&vis[p.x][p.y]==0){
     67                 p.step=t.step+1;
     68                 vis[p.x][p.y]=1;
     69                 if(p.x==n&&p.y==m){
     70                     s2=p.step;return ;
     71                 }
     72                 q.push(node(p.x,p.y,p.step));
     73             }
     74         }
     75     }
     76 }
     77 int main()
     78 {
     79     scanf("%d%d",&n,&m);
     80     getchar();
     81     for(int i=1;i<=n;i++){
     82         for(int j=1;j<=m;j++){
     83             scanf("%c",&mp1[i][j]);
     84         }
     85         getchar();
     86     }
     87     //getchar();
     88     for(int i=1;i<=n;i++){
     89         for(int j=1;j<=m;j++){
     90             scanf("%c",&mp2[i][j]);
     91         }
     92         getchar();
     93     }
     94     bfs1();
     95     bfs2();
     96     if(s1==1e9||s2==1e9||s1!=s2){
     97         cout<<"NO"<<endl;return 0;
     98     }
     99     for(int i=1;i<=n;i++){
    100         for(int j=1;j<=m;j++){
    101             if(mp1[i][j]=='*'&&mp2[i][j]=='*'){
    102                 mp1[i][j]='*';
    103             }
    104             else{
    105                 mp1[i][j]='#';
    106             }
    107         }
    108     }
    109     s1=1e9;
    110     bfs1();
    111     if(s1==s2){
    112         cout<<"YES"<<endl;
    113     }
    114     else{
    115         cout<<"NO"<<endl;
    116     }
    117     return 0;
    118 }
    View Code

    I :::

    思路::若a[i]与a[n-i-1]不等则令大的赋值成小的

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 const int maxn=1e5+5;
     5 const int inf=1e9+7;
     6 int gcd(int x,int y)
     7 {
     8     return y==0?x:gcd(y,x%y);
     9 }
    10 char a[maxn];
    11 int main()
    12 {
    13     int n;
    14     scanf("%s",a);
    15     n=strlen(a);
    16     for(int i=0;i<n/2;i++){
    17         if(a[i]==a[n-i-1]){continue;}
    18         if(a[i]>a[n-i-1]){
    19             a[i]=a[n-i-1];
    20         }
    21         else{
    22             a[n-i-1]=a[i];
    23         }
    24     }
    25     printf("%s
    ",a);
    26     return 0;
    27 }
    View Code
    纵使单枪匹马,也要勇闯天涯
  • 相关阅读:
    UVALive 6909 Kevin's Problem 数学排列组合
    UVALive 6908 Electric Bike dp
    UVALive 6907 Body Building tarjan
    UVALive 6906 Cluster Analysis 并查集
    八月微博
    hdu 5784 How Many Triangles 计算几何,平面有多少个锐角三角形
    hdu 5792 World is Exploding 树状数组
    hdu 5791 Two dp
    hdu 5787 K-wolf Number 数位dp
    hdu 5783 Divide the Sequence 贪心
  • 原文地址:https://www.cnblogs.com/sj-gank/p/11954128.html
Copyright © 2011-2022 走看看