江理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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
纵使单枪匹马,也要勇闯天涯