[考試反思]1027csp-s模擬測試90:自我

其實這套題很好。ios

可是此次,在T1爆炸的同時,T2和T3並無出現能彌補的表現。ide

在AK仍然存在的同時,我竟然連一個AC都沒有。ui

因此最後就是一無可取的一場。spa

考試結束前估分:100+100+30=230code

結果T1和T2都沒有A。。。blog

T1乖乖的按照題意打大模擬,沒算複雜度,開心的一匹。。。ci

T2位運算斷定鍋了,判斷兩個數二進制下的某幾位是否相同不能與運算完再與原數判。string

看到這句紅色加粗的話我本身也想笑了。。。怎麼能作到這麼蠢的啊。。?it

思路卻是對的,炸了50分。io

T3想到線段樹的正解,可是感受會嚴重炸精把線段樹弄成炸精樹,後來就開始yy題目裏的八分樹。

還有一個小時10分鐘的時候我打完了T1T2而後T3的30分暴力也寫完了。

此時腦子裏有一個不能讓本身相信的正解,以及不是很放心的T1T2。

很凌亂,而後我在再寫30分的部分分和嘗試打T3正解和檢查T1T2之間徘徊。

可是此次T1T2沒辦法對拍(沒有暴力。。。)

最後什麼都沒有幹成。剩15分鐘的時候決心打30部分分,結果沒調出來。

菜,仍是菜。

這一輪可能又要廢了。。。。。

哎,仍是少一點廢話吧。。。也改變不了什麼。。。

 

T1:新的世界

轉化題意,是最短路。

不難發現更新的前後順序與答案無關。

出題人精心構造數據,直接模擬T死,反順序dfs能極快AC。。。

唉。。。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 using namespace std;
 5 int n,m,A[505][505],L[505][505],r,c,l;
 6 const int xx[4]={0,0,1,-1};
 7 const int yy[4]={1,-1,0,0};
 8 #define tx x+xx[i]
 9 #define ty y+yy[i]
10 struct P{
11     int x,y,dt;
12     friend bool operator<(P a,P b){
13         return a.dt<b.dt;
14     }
15 };
16 priority_queue<P>q;
17 int main(){
18     scanf("%d%d",&n,&m);
19     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)scanf("%d",&A[i][j]);
20     scanf("%d%d%d",&r,&c,&l); L[r][c]=l; q.push((P){r,c,l});
21     for(int i=1;i<=n;++i)A[i][0]=A[i][m+1]=1234567890;
22     for(int i=1;i<=m;++i)A[0][i]=A[n+1][i]=1234567890;
23     scanf("%d%d",&r,&c);
24     while(!q.empty()){
25         int x=q.top().x,y=q.top().y,dt=q.top().dt;q.pop();
26         if(x==r&&y==c)return printf("%d\n",dt),0;        
27         for(int i=0;i<4;++i)if(L[tx][ty]<dt-A[tx][ty])
28             q.push((P){tx,ty,L[tx][ty]=dt-A[tx][ty]});
29     }puts("0");
30 }
View Code

 

 

 T2:鄰面合併

採用8進制壓位,一共8*3+1=25位

其中8個8進制數表示以某一個點爲起點的連續段終點是幾。

1~7分別對應2~8而終點是1的狀況與該起點不存在的狀況沒法區分。

那麼若是存在終點是1的話起點必定是1,特判,若是存在終點爲1的話,那麼就把狀態數+(1<<24)

搜索獲得,狀態數只有1597個,不均勻的分佈在256種限制裏。

預處理兩種狀態之間轉移的費用。枚舉上下兩層的決策便可。

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 vector<int>v[257];
 7 int ss[9],se[9],tp,cnt,ref[1605],L[257],R[257];
 8 int fee[1605][1605],dp[105][1605],st[102],ans=1234567890,n,m,x;
 9 void sch(int c){
10     int s=0,fs=0;
11     for(int i=1;i<=tp;++i)for(int j=ss[i];j<=se[i];++j)s|=1<<j-1;
12     for(int i=1;i<=tp;++i)fs|=se[i]-1<<3*ss[i]-3;
13     if(tp&&ss[1]==1&&se[1]==1)fs|=1<<24;
14     v[s].push_back(fs);
15     for(int s=c+1;s<=8;++s)for(int e=s;e<=8;++e)ss[++tp]=s,se[tp]=e,sch(e),tp--;
16 }
17 int main(){
18     sch(0);
19     for(int i=0;i<256;++i){
20         L[i]=cnt+1;
21         for(int j=0;j<v[i].size();++j)ref[++cnt]=v[i][j];
22         R[i]=cnt;
23     }
24     for(int i=1;i<=cnt;++i)for(int j=1;j<=cnt;++j){
25         int s=ref[j],sp=ref[j];
26         for(int t=9;t;--t,s>>=3)if(s&7)fee[i][j]++;
27         s=ref[i];
28         for(int t=9;t;--t,s>>=3,sp>>=3)if(s&7)if((s&7)==(sp&7))fee[i][j]--;
29     }
30     memset(dp,30,sizeof dp); dp[0][1]=0;
31     scanf("%d%d",&n,&m);
32     for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)scanf("%d",&x),st[i]|=x<<j-1;
33     for(int i=1;i<=n;++i)for(int j=L[st[i-1]];j<=R[st[i-1]];++j)
34         for(int k=L[st[i]];k<=R[st[i]];++k)
35             dp[i][k]=min(dp[i][k],dp[i-1][j]+fee[j][k]);
36     for(int i=L[st[n]];i<=R[st[n]];++i)ans=min(ans,dp[n][i]);
37     printf("%d\n",ans);
38 }
View Code

 

 

 T3:光線追蹤

能夠發現,每個矩形生效的只有左,下兩條邊。

一條邊固然在一段連續的角度露出。

在一個角度下多條邊,被看到的必定是橫/縱座標最小的。

若是座標相同,那麼編號大的更優。

而後就是維護結構體的區間修改單點查詢了。

對於橫着和豎着的邊分開維護,兩個線段樹便可(固然結構體封裝。。。)

可是線段樹固然不能基於浮點數,否則絕對就是個炸精樹

因此把全部要用到的浮點數都算出來,sort+unique離散化

用long double 就不會炸精,作乘除是用1.0l而不是1.0(Paris和kx的exp)

特殊處理x=0和y=0,方法不少。

個人方法是存下全部x=0,y=0的點的當前最小的另外一個座標以及編號。

同時,x=0的不能直接放進樹裏由於算角度時除0會爆炸。

可是咱們也不能把它直接扔掉無論由於0~rx的那一段橫着的線段可能還有用。

因此咱們把它強制設定爲1e-7而不是0就行了。

其實沒有那麼難碼。真心祝願你不要炸精。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 using namespace std;
 5 int opt[100005],ux[100005],uy[100005],dx[100005],dy[100006],tp,n,mnx0=1e9+7,mnxo,mny0=1e9+7,mnyo;
 6 long double r[300005];
 7 struct P{int ord,x;};
 8 P Max(P a,P b){return a.x<b.x?a:(a.x==b.x?(a.ord<b.ord?b:a):b);}
 9 int G(int p){return p>1000000000?0:p;}
10 struct Segment_Tree{
11     int cl[6666666],cr[6666666];P w[6666666];
12     void build(int p,int l,int r){
13         cl[p]=l;cr[p]=r;w[p]=(P){1000000001,1000000001};
14         if(l==r)return;
15         build(p<<1,l,l+r>>1);
16         build(p<<1|1,(l+r>>1)+1,r);
17     }
18     void set(int p,int l,int r,int ord,int x){
19         if(l<=cl[p]&&cr[p]<=r)return w[p]=Max(w[p],(P){ord,x}),(void)0;
20         if(l<=cr[p<<1])set(p<<1,l,r,ord,x);
21         if(r>=cl[p<<1|1])set(p<<1|1,l,r,ord,x);
22     }
23     P ask(int p,int pos){
24         if(cl[p]==cr[p])return w[p];
25         return Max(w[p],pos<=cr[p<<1]?ask(p<<1,pos):ask(p<<1|1,pos));
26     }
27 }X,Y;
28 main(){//freopen("raytracing4.in","r",stdin);freopen("my.out","w",stdout);
29     scanf("%d",&n);
30     for(int i=1;i<=n;++i){
31         scanf("%d",&opt[i]);
32         if(opt[i]==1){
33             scanf("%d%d%d%d",&dx[i],&dy[i],&ux[i],&uy[i]);
34             if(dx[i])r[++tp]=1.0L*dy[i]/dx[i],r[++tp]=1.0L*uy[i]/dx[i],r[++tp]=1.0L*dy[i]/ux[i];
35             else r[++tp]=dy[i]/1e-7L,r[++tp]=uy[i]/1e-7L,r[++tp]=dy[i]/ux[i];
36         }
37         else {
38             scanf("%d%d",&dx[i],&dy[i]);
39             if(dx[i])r[++tp]=1.0L*dy[i]/dx[i];
40         }
41     }sort(r+1,r+1+tp);tp=unique(r+1,r+1+tp)-r-1;
42     X.build(1,1,tp);Y.build(1,1,tp);
43     for(int i=1;i<=n;++i)if(opt[i]==1){
44         if(!dx[i])if(mnx0>=dy[i])mnx0=dy[i],mnxo=i;
45         if(!dy[i])if(mny0>=dx[i])mny0=dx[i],mnyo=i;
46         int x1=lower_bound(r+1,r+1+tp,1.0L*dy[i]/(dx[i]?dx[i]:1e-7L))-r,
47             x2=lower_bound(r+1,r+1+tp,1.0L*uy[i]/(dx[i]?dx[i]:1e-7L))-r,
48             x3=lower_bound(r+1,r+1+tp,1.0L*dy[i]/ux[i])-r;
49         X.set(1,x1,x2,i,dx[i]); Y.set(1,x3,x1,i,dy[i]);
50     }else{
51         if(!dx[i]){printf("%d\n",mnxo);continue;}
52         if(!dy[i]){printf("%d\n",mnyo);continue;}
53         P a1=X.ask(1,lower_bound(r+1,r+1+tp,1.0L*dy[i]/dx[i])-r),
54           a2=Y.ask(1,lower_bound(r+1,r+1+tp,1.0L*dy[i]/dx[i])-r);
55         int fx=a1.x,fy=a2.x;
56         if(1ll*fx*dy[i]==1ll*fy*dx[i])printf("%d\n",G(max(a1.ord,a2.ord)));
57         else if(1ll*fx*dy[i]<1ll*fy*dx[i])printf("%d\n",G(a1.ord));
58         else printf("%d\n",G(a2.ord));
59     }
60 }
View Code
相關文章
相關標籤/搜索