埃森哲杯第十六屆上海大學程式設計聯賽春季賽暨上海高校金馬五校賽 EALFID
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;
}