EZ 2018 03 23 NOIP2018 模拟赛(五)
鏈接:http://211.140.156.254:2333/contest/65
這次Rating重回Rank18,我是20的守門員(滑稽)
這次題目和數據普遍偏水,我T2打錯了一個變量名竟然過了所有的樣例而且有90分(滑稽)
但最后一題SB了,忽略了還有不為2的幾次冪的情況,所以炸成10分。
200分竟然Rank6,不過xu‘yi’zhou大佬直接AK了這場比賽。
T1 類歐幾里得算法(不存在的,爆搜+打表找規律)
給出的標算是這樣的:
比較簡單的類歐幾里得算法,考慮如果當前所需電阻
- 大于1,串聯 1Ω 電阻
- 小于1,并聯 1Ω 電阻
然后給出我的算法:
首先根據簡單的物理學知識,可以得到當目前電阻為a/b時,再加上一個電阻的情況有:
a+b/b(串聯上一個1Ω的電阻)
a/a+b(并聯上一個1Ω的電阻)
所以我們暴力廣搜,別指望過去
然后準備好紙和筆,令讀入的兩個數為a/b,開始:
for (a=1;;++a)
for (b=1;;++b)
讓你的暴力開始跑吧,我們定義ans=(a,b)
可以得到這些性質:
(a,1)=(1,a)=a
(a,b)=(b,a)
(a,b+a)=(a,b)+b/a
然后發現這些性質后就可以直接遞歸求解了(我用了迭代,注意邊界為a=1)
CODE
#include<cstdio> using namespace std; typedef long long LL; LL a,b,ans; inline void swap(LL &a,LL &b) {LL t=a; a=b; b=t; } int main() {//freopen("A.in","r",stdin); freopen("A.out","w",stdout);scanf("%lld%lld",&a,&b);for(;;){if (a>b) swap(a,b);if (a==1) { printf("%lld",ans+b); break; }if (b%a==0) { printf("%lld",ans+b/a); break; }ans+=b/a; b%=a;}return 0; }?
T2 一道比較簡單的貪心題目
先把數組sort一遍,如果沒有1的話就輸-1
考慮已經能組合出?1~x?的數值
那么下一個硬幣取?x?以內最大的數?k
使能組合出?1~x+k,直到得到要求的個數
由于這里x的范圍較大,所以每一次推進不能拿來加(要不然就等著吃TLE吧),%一下即可
CODE
#include<cstdio> #include<algorithm> using namespace std; typedef long long LL; const LL N=1000005; LL a[N],ans,x,n,now,last; inline char tc(void) {static char fl[100000],*A=fl,*B=fl;return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline void read(LL &x) {x=0; char ch=tc();while (ch<'0'||ch>'9') ch=tc();while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc(); } int main() {//freopen("B.in","r",stdin); freopen("B.out","w",stdout);register int i;read(x); read(n);for (i=1;i<=n;++i)read(a[i]);sort(a+1,a+n+1);if (a[1]!=1) { puts("-1"); return 0; }ans=now=last=1; a[n+1]=x+1; while (now<x){while (now>=a[last+1]-1&&last<n) ++last;if (last==n) { ans+=(x-now)/a[last]; break; }ans+=(a[last+1]-now-2)/a[last]+1; now+=((a[last+1]-now-2)/a[last]+1)*a[last];}printf("%lld",ans);return 0; }?
T3 首先可以考慮一下性質:對于數列中的數,如果不是2的整數冪只要在最后乘上去就可以了(原理很簡單,主要開始沒想到這個導致寫了一個可以過的DP但后來放棄了)
還有一點,當所有的數都是2的冪次的時候,判斷是否可以合出2048只需要判斷它們的和是否達到2048即可(可以自己想像2進制的加法,就是2048的原理)
所以我們用一個類似于背包的東西來記錄所有價值和小于2048的方案(大于的可能會很麻煩),用子段的總數減去即可。
所有還要乘上非2的冪次的數,由于全部都是2的冪次,快速冪求之。
CODE
#include<cstdio> using namespace std; const int P=2048,mod=998244353; int f[P],n,x,m,tot,ans; inline char tc(void) {static char fl[100005],*A=fl,*B=fl;return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline void read(int &x) {x=0; char ch=tc();while (ch<'0'||ch>'9') ch=tc();while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc(); } inline void inc(int &x,int y) {if ((x+=y)>=mod) x-=mod; } inline void dec(int &x,int y) {if ((x-=y)<0) x+=mod; } inline int quick_pow(int x,int p) {int res=1;while (p){if (p&1) res=((long long)res*x)%mod;x=((long long)x*x)%mod;p>>=1;}return res; } int main() {//freopen("C.in","r",stdin); freopen("C.out","w",stdout);register int i,j;read(n); f[0]=1;for (i=1;i<=n;++i){read(x);if (x^(x&-x)) continue;for (++m,j=P-1;j>=x;--j)inc(f[j],f[j-x]);}for (i=0;i<P;++i)inc(tot,f[i]);int now=quick_pow(2,m);dec(ans=quick_pow(2,m),tot);ans=((long long)ans*quick_pow(2,n-m))%mod;printf("%d",ans);return 0; }?
轉載于:https://www.cnblogs.com/cjjsb/p/8645296.html
總結
以上是生活随笔為你收集整理的EZ 2018 03 23 NOIP2018 模拟赛(五)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux命令一
- 下一篇: 一篇关于Maven项目的jar包Shel