1. 程式人生 > >9.14 模擬賽

9.14 模擬賽

code mes string str clu 編號 tin 水題 ace

模擬賽第三彈~

T1

題意:給你一個數列,要求刪掉任意一種整數,使得剩下的新數列中連續的相等的數最多

例如 2 7 3 7 7 3 3 7 7 5 7,刪掉3以後剩的7有四個連續的,最多

思路:暴力枚舉去掉哪個......這算是一道水題吧

代碼丟了...... TAT

T2

題意:有n本書,每本書有寬度和高度。現在你有無數個書架,每個書架的寬度為w,高度由最高的書決定

問在書本按順序放的情況下,總的書架高度最小是多少

思路:dp,dp[i]表示做到第i本書時的最小高度和。

每次先找到能以編號j的書開始,編號i結束的一批書能放在同一個書櫃裏時,j的最小值,

然後枚舉j到i-1,查找這一批書的最大值,dp[i]=min(dp[j]+max_height(h[j]~h[i]))

寬度前綴和,高度線段樹

代碼丟了*2

T3

題意:有一頭牛,坐標(bx,by),n個柱子,橫坐標都是cx,縱坐標是cy[i]

現在從牛身上開始有m段繩子,每個繩子有起點和終點坐標,繞在牛身上成為一圈

問最少拔掉幾個柱子,能讓牛逃走

思路:非常規題目,第一眼以為wind算法......

然而正解到現在都沒看懂,挖坑*1

T4

題意:有n頭牛(n<=20),每個牛有產奶量a[i],現在讓你在所有牛中選出一部分,使得這些牛可以分成產奶量相同的兩組

問:一共有多少種選擇方法

思路:折半搜索(meet in the middle),先把兩邊的所有方法搜出來(狀壓方法表示),然後雙指針維護,每次用位運算查看一下當前的合法狀態是否已經算過

對於左邊(i=1~n/2)和右邊(i=n~n/2+1)的dfs,每次有三種情況:放在A組,放在B組,不選

這樣最後只要看左邊和右邊dfs得出的所有情況裏面,| Ai-Bi | (left) ==| Ai-Bi | (right) 的有多少組(不重復的)

代碼(終於找到了!!!!):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct node{
    
int s,x,next; }l[1100010],r[1100010]; int n,a[30],firstl[10010],firstr[10010],totl,totr; void dfs1(int k,int sum,int s){ if(k==n/2+1){ if(sum>=0){ l[++totl].s=s;l[totl].x=sum; l[totl].next=firstl[s];firstl[s]=totl; } return; } dfs1(k+1,sum,s); dfs1(k+1,sum+a[k],s|(1<<(k-1))); dfs1(k+1,sum-a[k],s|(1<<(k-1))); } void dfs2(int k,int sum,int s){ if(k==n/2){ if(sum>=0){ r[++totr].s=s;r[totr].x=sum; r[totr].next=firstr[s];firstr[s]=totr; } return; } dfs2(k-1,sum,s); dfs2(k-1,sum+a[k],s|(1<<(n-k))); dfs2(k-1,sum-a[k],s|(1<<(n-k))); } bool vis[5001000]={0}; bool cmp(node x,node y){ return x.x<y.x; } int main(){ int i,p1,p2,tmp1,tmp2,ans=0; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); dfs1(1,0,0);dfs2(n,0,0); sort(l+1,l+totl+1,cmp);sort(r+1,r+totr+1,cmp); p1=1;p2=1; while(p1<=totl&&p2<=totr){ if(l[p1].x>r[p2].x){ p2++;continue; } if(l[p1].x<r[p2].x){ p1++;continue; } tmp1=p1;tmp2=p2; while(l[p1].x==l[tmp1].x) p1++; while(r[p2].x==r[tmp2].x){ for(i=tmp1;i<p1;i++){ if(!vis[((r[p2].s)<<(n/2))|l[i].s]){ ans++;vis[((r[p2].s)<<(n/2))|l[i].s]=1; } } p2++; } } printf("%d",ans-1); }

總分:240+,自我感覺良好ing

然而對於代碼實現(第四題)還是要加強啊......

9.14 模擬賽