江理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("\n");
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\n");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\n",(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\n",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\n");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\n",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\n",a);
26     return 0;
27 }
View Code

 

posted @ 2019-11-28 22:04  sj-_-js  阅读(248)  评论(0编辑  收藏  举报