E
https://www.nowcoder.com/acm/contest/91/E
按照题意 打个表 发现答案是2的n次方
#include<bits/stdc++.h> using namespace std; int main(){ int n; while(cin>>n) { long long int ans=pow(2,n); cout<<ans<<endl; } return 0; }
A
https://www.nowcoder.com/acm/contest/91/A
贪心,将缺泥土的和多泥土的2堆分开,再按照位置排序,那么最前面的缺泥土的一定是从最前面的多泥土的一堆里面拿泥土最优
#include<bits/stdc++.h> using namespace std; struct node{ long long wz; long long da; }; long long a[111111]; long long b[111111]; node co[111111]; node pa[111111]; node co1[111111]; node pa1[111111]; int main(){ int t; cin>>t; while(t--) { int n; cin>>n; for(int i=0;i<n;i++) scanf("%lld",&a[i]); int jc=0; int jp=0; for(int i=0;i<n;i++) { scanf("%lld",&b[i]); a[i]-=b[i]; if(a[i]<0) { co[jc].wz=i; co[jc++].da=a[i]; co1[jc-1]=co[jc-1]; } else if(a[i]>0) { pa[jp].wz=i; pa[jp++].da=a[i]; pa1[jp-1]=pa[jp-1]; } } long long ans=0; int zc=0; int zp=0; while(zc<jc&&zp<jp) { if(co[zc].da+pa[zp].da<0) { ans+=pa[zp].da*(abs(co[zc].wz-pa[zp].wz)); co[zc].da+=pa[zp].da; zp++; } else if(co[zc].da+pa[zp].da==0) { ans+=pa[zp].da*(abs(co[zc].wz-pa[zp].wz)); zp++; zc++; } else{ ans-=co[zc].da*(abs(co[zc].wz-pa[zp].wz)); pa[zp].da+=co[zc].da; zc++; } } cout<<ans<<endl; } return 0; }
L
https://www.nowcoder.com/acm/contest/91/L
背包题,求最长子序列,且该序列的和是k的倍数,那么我们可以将全部求和mod k,那么问题就变成了,我们需要挑出尽量少的数字,并且这些数字求和mod k等于之前全部求和mod k的值,这个时候就可以用背包来更新了,注意更新的时候要注意dp数组下标需要取模
#include<bits/stdc++.h> using namespace std; long long a[111111]; int dp[10011111]; int main(){ int t; int n,k; while(cin>>n>>k) { int sum=0; for(int i=0;i<n;i++) { scanf("%lld",&a[i]); a[i]%=k; sum=(sum+a[i]%k)%k; } for(int i=0;i<=k;i++) dp[i]=-1; dp[0]=0; for(int i=0;i<n;i++) { for(int j=sum;j>=0;j--) { if(dp[(j+k-a[i])%k]!=-1) { if(dp[j]==-1) dp[j]=dp[(j+k-a[i])%k]+1; else dp[j]=min(dp[j],dp[(j+k-a[i])%k]+1); } } } //for(int i=0;i<=k;i++)
#include<bits/stdc++.h> using namespace std; char a[111111]; int main(){ int t; cin>>t; while(t--) { cin>>a; int l=strlen(a); int flag=0; int f=0; for(int i=0;i<l;i++) { if((a[i]-'0')%2==0&&flag==0)continue; if((a[i]-'0')%2==1&&flag==0) { flag=1; if(i==l-1) { a[i]=a[i]-1; } else{ if(a[i]=='9') { a[i]='8'; a[i+1]='8'; f=1; } else{ int jw=i+1; while(a[jw]=='4'&&jw<=l-1) { jw++; } if(a[jw]>'4'&&jw<=l-1) { f=-1; a[i]=a[i]+1; } else { f=1; a[i]=a[i]-1; } } } continue; } if(f==1) { a[i]='8'; } else { a[i]='0'; } } int fff=0; for(int i=0;i<l;i++) { if(a[i]!='0')fff=1; if(fff==0)continue; cout<<a[i]; } if(fff==0) cout<<"0"<<endl; else cout<<endl; } return 0; }
//{ // cout<<dp[i]<<endl; //} cout<<n-dp[sum]<<endl; } return 0;}
I
https://www.nowcoder.com/acm/contest/91/I
求离n最近的二数是多少,很容易可以想到高位开始,如果是偶数则继续看,当第一次遇到一个奇数的时候,那么就有2中操作,要不就是加一要不就减一,如果加一的话,为了让答案更接近n,那么这个奇数后面的数因为这个奇数变大了,那么后面的数应该变小,既然要变小而且还都是偶数,那么只能是全是0了,减一的话类似加一只不过后面的数都是8了,那么就要比一下全变成8和全变成0的情况哪个更接近 n,因为数很大所以不能求和来比较,因为0和8的平均数是4,所以只要从高位往地位遍历,找到第一个不等于4的数,如果大于4则选择全变为0,小于4则全变为8;
ex:248647444444544444444444444
答案应该是248648000000000000000000000 细节:如果第一个奇数就是9的话,是不可能选择加一的...很明显
F
https://www.nowcoder.com/acm/contest/91/F
打表发现规律, 和2的幂次方有关, 用java写的大数
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args){ BigInteger a; Scanner cin=new Scanner(System.in); a=cin.nextBigInteger(); while(a.equals(BigInteger.ZERO)!=true) { a=a.subtract(BigInteger.ONE); BigInteger b=cin.nextBigInteger(); if(b.equals(BigInteger.ONE)==true) { System.out.println("1"); continue; } BigInteger ans=BigInteger.ZERO; while(b.equals(BigInteger.ZERO)==false) { int js=0; BigInteger x=BigInteger.ONE; BigInteger y=BigInteger.ONE; while(b.compareTo(x.add(y))>=0) { BigInteger t=y; y=y.add(x); x=t; js++; } BigInteger er=BigInteger.ONE.add(BigInteger.ONE); BigInteger zs=BigInteger.ONE; for(int i=1;i<=js;i++) { zs=zs.multiply(er); } ans=ans.add(zs); b=b.subtract(y); } System.out.println(ans); } } }
D
https://www.nowcoder.com/acm/contest/91/D
数据水了..应该
#include<bits/stdc++.h> using namespace std; char a[111111]; int main(){ int t; cin>>t; while(t--) { int a,b,c,d,e; cin>>a>>b>>c>>d>>e; if(d-c+1>=e) { cout<<"LOSE"<<endl; } else cout<<"WIN"<<endl; } return 0; }