日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

3.18 UR17

發(fā)布時間:2024/4/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3.18 UR17 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

打了UOJ Round 17,這么低的分居然還漲rating?!
T1:
開始讀錯題了,1h以后寫的暴力過不了樣例開始慌,手玩樣例發(fā)現(xiàn)讀錯題了,然而并沒有時間改,寫了子任務(wù)123就跑了。
T2:
計算幾何的氣息,直接跳過。
T3:
概率期望?看來沒得做了。手玩了菊花圖的10分,打個表發(fā)現(xiàn)其余的跑不出來,棄掉了。
捆綁測試,有分基本上也都卡沒了。

題解:
T1:
最優(yōu)答案肯定是一條鏈。
對于任務(wù)34,我們可以直接找最小的,最多l(xiāng)og次就會減到最小,復(fù)雜度\(O(n*log_{2}{n})\)
對于任務(wù)5,我們可以枚舉一下a[i],設(shè)計狀態(tài)數(shù)組f[i]表示在狀態(tài)i時,變成0最少需要多少代價。
f[i]=min(f[i],f[i&a[i]]+a[i]),復(fù)雜度\(O(n*max_w)\)
滿分做法是我們不枚舉a[i],而是枚舉一個子集S,找a[]中是否有一個數(shù)和它與起來為0.
這樣先預(yù)處理a[i]補(bǔ)集的子集就可以了,復(fù)雜度是\(O(3^{log_{2}max_w})\)
轉(zhuǎn)移方程就變成了\(f[i]=min(f[i],f[i^s]+i^s)\)
注意可能所有的數(shù)與起來不為0,在總的或起來的數(shù)異或上它就可以了。

#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; #define int long long #define mmin(a,b) (a<b?a:b) int n,f[601000],a[601000]; bool pd[601000]; signed main() { // freopen("ex_treeand3.in","r",stdin);scanf("%lld",&n);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);int all=0,zz=0;for(int i=1;i<=n;i++) all|=a[i];zz=all;for(int i=1;i<=n;i++) zz&=a[i];sort(a+1,a+n+1);for(int i=1;i<=n;i++){pd[all^a[i]]=1;a[i]^=zz;}all^=zz;pd[0]=1;for(int i=all;i>=0;i--){if(zz&i) continue;for(int j=0;j<=18;j++){if(zz&(1<<j)) continue;pd[i]|=pd[i|(1<<j)];}}memset(f,30,sizeof(f));f[0]=0;for(int i=1;i<=all;i++){if(i&zz) continue;for(int j=i;j;j=(j-1)&i){if((i^j)>f[i]) break;if(pd[j]) f[i]=mmin(f[i],f[i^j]+(i^j));}}printf("%lld",f[all]+zz*n);return 0; }

T2:
對于一定在端點的情況,我們設(shè)狀態(tài)數(shù)組f[i][j],表示一個點為i,另一個點為j時是否能夠到達(dá)(stx,sty);
然后二分答案,記憶化一下,復(fù)雜度\(O(n^2*log_{2}n)\)
滿分做法:
仍然是二分答案。
設(shè)狀態(tài)數(shù)組f[i][j]表示一個點在第i個節(jié)點,一個點在第j條邊上是否合法。
i和j的最小距離必須小于等于二分的答案v。
由于把一條直線擺直時,另一條直線一定單調(diào),所以取最小距離就可以了。
f[i][j]可以有f[k][j]轉(zhuǎn)移過來,k為j的某個端點,j為與i相連的直線;或f[k][j],k與i相連。
仍然是bfs一下,復(fù)雜度\(O(n^2*log_{2}n)\)

#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <queue> using namespace std; #define fang(x) ((x)*(x)) #define pai pair<int,int> struct point{double x,y;int id; }q[1010]; point operator + (const point &s1,const point &s2) {return (point){s1.x+s2.x,s1.y+s2.y};} point operator - (const point &s1,const point &s2) {return (point){s1.x-s2.x,s1.y-s2.y};} double operator * (const point &s1,const point &s2) {return s1.x*s2.y-s1.y*s2.x;} struct line{point a,b; }l[1010]; int n,f[1010][1010],du[1010],stx,sty; double eps=1e-7; void bfs(double); vector<int> ve[1010]; double getdisxian(point,line); double getdisdian(point,point); point getpoint(line,line); bool check(double); signed main() { // freopen("in.txt","r",stdin);scanf("%d%d%d",&n,&stx,&sty);for(int i=1;i<=n;i++) scanf("%lf%lf",&q[i].x,&q[i].y),q[i].id=i;for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);l[i].a=q[x]; l[i].b=q[y];if(q[x].x>q[y].x) swap(l[i].a,l[i].b);du[x]++; du[y]++;ve[x].push_back(i);ve[y].push_back(i);}double le=0,ri=2e6;while(ri-le>eps){double mid=(le+ri)*0.5;bfs(mid);if(check(mid)==1) ri=mid;else le=mid;}printf("%.7f",le);return 0; } void bfs(double xian) {memset(f,0,sizeof(f));if(getdisdian(q[stx],q[sty])>xian) return ;queue<pai> que; // cout<<getdisxian(q[8],l[5])<<endl;for(int i=1;i<=n;i++){if(du[i]!=1) continue;for(int j=1;j<=n;j++){if(du[j]==1){if(getdisdian(q[i],q[j])>xian){f[i][ve[j][0]]=-1;continue;}if(getdisxian(q[i],l[ve[j][0]])>xian){f[i][ve[j][0]]=-1;continue;}f[i][ve[j][0]]=1;que.push((pai){i,ve[j][0]});}}}int sz;while(que.empty()==0){pai x=que.front(); que.pop();sz=ve[x.first].size();for(int i=0;i<sz;i++){int xi=ve[x.first][i];if(f[l[x.second].a.id][xi]==0){if(getdisxian(l[x.second].a,l[xi])<xian){f[l[x.second].a.id][xi]=1;que.push((pai){l[x.second].a.id,xi});}else{f[l[x.second].a.id][xi]=0;}}if(f[l[x.second].b.id][xi]==0){if(getdisxian(l[x.second].b,l[xi])<xian){f[l[x.second].b.id][xi]=1;que.push((pai){l[x.second].b.id,xi});}else{f[l[x.second].b.id][xi]=0;}}}} } double getdisdian(point a,point b) {return sqrt(fang(a.x-b.x)+fang(a.y-b.y)); } double getdisxian(point a,line b) {point c;if(fabs(b.a.y-b.b.y)<eps) c.x=a.x,c.y=a.y+1;else{double k;if(fabs(b.a.x-b.b.x)<eps) k=0;else k=(b.a.y-b.b.y)/(b.a.x-b.b.x),k=-1.0/k;c.x=a.x+1; c.y=a.y+k;}point d=getpoint((line){a,c},b);if(d.x<=b.b.x&&d.x>=b.a.x) return getdisdian(a,d);else{if(d.x<b.a.x) return getdisdian(a,b.a);else return getdisdian(a,b.b);} } point getpoint(line a,line b) {point p;double dot1=(b.a-a.a)*(b.b-a.a),dot2=(b.b-a.b)*(b.a-a.b);p.x=(a.a.x*dot2+a.b.x*dot1)/(dot1+dot2);p.y=(a.a.y*dot2+a.b.y*dot1)/(dot1+dot2);return p; } bool check(double xian) {if(getdisdian(q[stx],q[sty])>xian) return false;for(int i=0;i<ve[stx].size();i++)if(f[sty][ve[stx][i]]==1)return true;for(int i=0;i<ve[sty].size();i++)if(f[stx][ve[sty][i]]==1)return true;return false; }

T3:
題解和代碼都鴿了……

轉(zhuǎn)載于:https://www.cnblogs.com/hzoi-wangxh/p/8641636.html

總結(jié)

以上是生活随笔為你收集整理的3.18 UR17的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。