江理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 :::

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

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

由题意可以知当你在某两点之间建立边时,你只会用 X,Y,Z 中的一种建立,而对X排序的话保证了相邻的两点建边花费最小(必然不会选择与其他点建立),对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 :::

思路::

 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 :::

思路::

阶乘逆元模板

 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

猜你喜欢

转载自www.cnblogs.com/sj-gank/p/11954128.html