[考試反思]1031csp-s模擬測試95:優勢


假的三首殺。因為交文件所以他們都不往OJ上交。

假裝是三首殺吧。嗯。

然而昨天還是沒有AK。好像說是按照64位評測機的評測結果為准。

但是聯賽省選的機子好像都是32位的?也就是和我們正在用的一致。

所以代碼放在聯賽上也能過,沒鍋就行,天災人禍丟了40分那就沒辦法了。

關鍵是在自己的機子上怎么測都能過,而且還不能模擬評測機環境,昨天我在本機測了一組最大數據才交的。

因為64位機在遞歸的時候int的棧空間是按照8bit算的(強制開long long??),所以我就爆棧了。

(200000深度的dfs我申請了7個int,大約是5.3MB,而評測機按8位算之后變成了10.6MB)

但是不管怎么說也是漲了個記性,在題目沒有說明無限棧的情況下棧空間就是8MB,不要炸。

(雖說平時自己機子上跑出來了就沒什么問題。據說今天就是按照32位評測機的結果為准的)

(尚無定論,我還是不瞎說了,實在不行以后就按照4MB算)

回到今天。所以今天才是自己這輩子第一次AK非B組題,也是第一次三首殺AK。

昨天白高興了。。。rank5還在講題的時候上去說了半天現在想想十分尷尬。。。

但是這兩天的題都比較合我的胃口。而且這次很沒水准。

T1打表找規律。T2復雜版原題。T3算是自己想出來的(其實不是特別難想所以沒什么可開心的)。

沒有大數據結構,部分分給的很全而且還有提示意義,思考量也剛好合適。

所以做的順手了分就上去了。這兩天還在寫對拍所以沒出什么意外(呃。。。在能力范圍內沒什么意外。。。64位就算了)

我還是希望如果遇到不順手的題也能像這樣穩住心態不斷的思考盡力的拿分保分吧。。。

 

T1:簡單計算

打表找規律得到的式子(我愛打表找規律)

懶得寫Latex了,不粘題面粘題解應該沒什么事吧(不然其實也就是抄一遍)

打表找規律不乏是一個考場上的好技巧啊2333

1 #include<cstdio>
2 int gcd(int a,int b){return b?gcd(b,a%b):a;}
3 int main(){freopen("simplecalc.in","r",stdin);freopen("simplecalc.out","w",stdout);
4     int t,p,q,g;scanf("%d",&t);
5     while(t--)scanf("%d%d",&p,&q),g=gcd(p,q),printf("%lld\n",(p+1ll)*q/2-(p-1)/2+(g-1)/2);
6 }
呃。。。6行

 

T2:格式化

如果只有收益,那么當然按照格式化之前的容量從小到大挨個來。

如果只有虧損,那么當然按照格式化之后的容量從大到小挨個來。(完全反過程,和B組原題一樣)

如果有收益有虧損,那么肯定先收益后虧損。

是一個比較普通也不是很不可證的貪心。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 struct P{int lim,E;}A[1000005],B[1000005];
 5 bool comA(P x,P y){return x.lim<y.lim;}
 6 bool comB(P x,P y){return x.E>y.E;}
 7 long long res,ans;int n,cA,cB;
 8 int main(){
 9     freopen("reformat.in","r",stdin);
10     freopen("reformat.out","w",stdout);
11     scanf("%d",&n);
12     for(int i=1,od,nw;i<=n;++i){
13         scanf("%d%d",&od,&nw);
14         if(nw>=od)A[++cA]=(P){od,nw};
15         else B[++cB]=(P){od,nw};
16     }
17     sort(A+1,A+1+cA,comA);
18     for(int i=1;i<=cA;++i)
19         if(res<A[i].lim)ans+=A[i].lim-res,res=A[i].E;
20         else res+=A[i].E-A[i].lim;
21     sort(B+1,B+1+cB,comB);
22     for(int i=1;i<=cB;++i)
23         if(res<B[i].lim)ans+=B[i].lim-res,res=B[i].E;
24         else res+=B[i].E-B[i].lim;
25     printf("%lld\n",ans);
26 }
View Code

 

T3:真相

暫且把第一種類型的人稱為“預言家”吧。

我不會狼人殺!!!

如果沒有預言家,那么可以O(n)爆掃。(枚舉第一個人的真假,然后遞推到第n個人看是否矛盾)

如果有預言家,那么可以先枚舉某一個預言家為真,然后其它所有人都可以遞推得到。

(其它預言家的k值如果與你判定為真的預言家不同那么必定為假,其余預言家為真,其他人可以根據順時針下一個人推出)

(也就是,每個語言家直接決定了向前一直走到上一個預言家的位置這一段區間內所有人的真假狀態)

還要考慮所有預言家都是假的情況,這樣的話也是可以線性遞推的,不過最后要看一下得到的說真話的人數不能與任何一個預言家所說的一致。

到這里就是$O(n^2)$的了。

可以發現一個問題,每一次你枚舉不同的預言家為真時,除了這兩個預言家外剩下預言家所控制的區間其實都沒有變化。

我們對所有預言家都為假時的總共的說真話人數求和,再把k值相同的預言家壓成一個。

每次考慮一個k值時,從你的求和值里減去這類預言家的貢獻,再加上這個預言家說真話的貢獻。

(然而我枚舉的不是k值,而是所有k值不同的預言家)

判斷此時說真話的人數是否符合即可。

再說一遍不要忘了所有預言家都是假的的情況。

還要注意,這題沒有給出對k值的限制,所以直接枚舉k值可能是錯誤的。

實際上數據里滿足$0 \leq k$,但是還是有人跪在了$k=0$的情況上。

(update:存在$k > n$的數據!!)

考場上我也不知道k的范圍所以我是枚舉的所有預言家的k值,這樣的話會更嚴謹一些。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int opt[100005],k[100005],n,spj,pcnt,re[100005],consistent,inconsistent;
 4 int r(int p){return p>n?1:p;}
 5 struct P{
 6     int K,t,f,u;
 7     friend bool operator<(P a,P b){
 8         return a.K<b.K;
 9     }
10 }p[100005];
11 bool chk(){
12     re[1]=1;
13     for(int i=2;i<=n;++i)re[i]=re[i-1]^opt[i-1];
14     if(re[1]==(re[n]^opt[n]))return true;
15     re[1]=0;
16     for(int i=2;i<=n;++i)re[i]=re[i-1]^opt[i-1];
17     if(re[1]==(re[n]^opt[n]))return true;
18     return false;
19 }
20 main(){
21     freopen("truth.in","r",stdin);
22     freopen("truth.out","w",stdout);
23     int t;char s[3];
24     scanf("%d",&t);
25     while(t--){
26         scanf("%d",&n);spj=pcnt=consistent=inconsistent=0;
27         for(int i=1;i<=n;++i){
28             scanf("%s",s);
29             if(s[0]=='$')scanf("%d",&k[i]),opt[i]=-1,spj=1;
30             else if(s[0]=='+')opt[i]=0;
31             else opt[i]=1;
32         }
33         if(!spj){puts(chk()?"consistent":"inconsistent");continue;}
34         for(int i=1;i<=n;++i)if(opt[i]==-1){
35             int j=i-1;if(!j)j=n;re[i]=1;
36             p[++pcnt]=(P){k[i],1,0,0};
37             while(opt[j]!=-1){
38                 re[j]=re[r(j+1)]^opt[j];
39                 if(re[j])p[pcnt].t++;else p[pcnt].f++;
40                 j--;if(!j)j=n;
41             }
42         }
43         sort(p+1,p+1+pcnt);
44         int lst=0;p[0].K=-20030208;
45         for(int i=1;i<=pcnt;++i)
46             if(p[i].K==p[lst].K)p[lst].t+=p[i].t,p[lst].f+=p[i].f,p[i].u=1;
47             else lst=i;
48         int totf=0;
49         for(int i=1;i<=pcnt;++i)if(!p[i].u)totf+=p[i].f;
50         for(int i=1;i<=pcnt;++i)if(!p[i].u)if(p[i].K==totf-p[i].f+p[i].t)consistent=1;
51         for(int i=1;i<=pcnt;++i)if(p[i].K==totf)inconsistent=1;
52         puts((consistent||!inconsistent)?"consistent":"inconsistent");
53     }
54 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM