首先 \(0<=a<=b<=c\)
會隨機給出
\(a+b,a+c,b+c,a+b+c\)的值node
由於\(a,b,c\)都爲正整數,因此\(a+b+c\)必定爲最大值
而後用\(a+b+c\)逐個減去便可(注意\(a,b,c\)大小ios
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; int x[5]; int main(){ for(int i=1;i<=4;++i) cin>>x[i]; sort(x+1,x+5); for(int i=3;i>=1;--i) cout<<x[4]-x[i]<<" "; return 0; }
根據題意模擬,不難想到暴力枚舉,枚舉出每個由原數刪了後的數
再看數據範圍,數的長度最多十位,因此每一個數最多枚舉2^10次,每次枚舉最多10次,\(t<=10\)組數據
n爲數的長度
因此時間複雜度\(O(2^n*n*t)\)spa
利用二進制
舉個例子
原數\(2081\)
$(1010)_2 $ 1就表明不刪相應位置數,0表明刪了相應位置的數
按照上述規則,刪了後的數爲 28
\((0111)_2\) 刪了後的數字爲 081 ,但這裏你會發現有前導0,但其實具體實現的時候不會有這個問題,由於咱們是一位一位的轉化成整型,巧妙的避免了前導0的問題
既然是找最少次刪除操做
那枚舉順序\(0-2^n\)code
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> using namespace std; string s; int t; int stlen(int x){//求x的位數 int ans=0; for(;x;++ans) x/=10;return ans; } int main(){ cin>>t; while(t--){ cin>>s; int len=s.length(); int ans=100; for(int i=0;i<(1<<len);++i){ int x=0; for(int j=0;j<len;++j) if(i>>j & 1) x=x*10+s[j]-'0'; int sq=sqrt(x); if(x && sq*sq==x) ans=min(ans,len-stlen(x)); } if(ans!=100) cout<<ans<<endl; else cout<<"-1"<<endl; } }
突破口 :只且必須選出兩個特殊點
那麼考慮三種狀況
設兩個特殊點分別爲\(x,y\)排序
選了\(x,y\)但不通過任意\(x,y\)ci
通過兩個\(x,y\)最短路徑是從\(1——>n\)get
通過兩個\(x,y\)最短路徑是從\(n——>1\)string
設\(dis1[],dis2[]\)分別爲1到各個點的最短距離,n到各個點的最短距離
三種狀況分別能得出的答案即爲
1.\(dis1[n]\) (不通過任何點即爲最短路
2.\(dis1[x]+1+dis2[y]\) (1——>x+x——>y+y——n
3.\(dis2[x]+1+dis1[y]\) (n——>x+x——>y+y——1it
求出後兩種狀況的最大值以後
在三者狀況種取最小值(爲何不取較大兩個值,由於較大兩個雖然構成最短路,但在三種狀況一塊兒討論的時候,並不較大的兩個值並不構成最短路
也就是說,添加一條邊以後頗有可能最短距離會減少)io
第一狀況跑一下最短路就可
第二種和第三種狀況,首先要預處理
\(dis1[]和dis2[]\),跑一遍最短路便可
最終求的是1到n最短距離儘量大
因此如今的目標就是求出2,3狀況的最大值,取其中得最小值(
若是暴力求話直接GG
假設\((i,j)\)爲一對且\(i!=j\),並且i,j∈特殊點
任取一對,則二三狀況獲得的答案
\(max(min(dis1[i]+1+dis2[j],dis1[j]+dis[i]+1))\)
當dis1[i]+1+dis2[j]<=dis1[j]+dis[i]+1時
即dis1[i]-dis2[i]<=dis[j]-dis2[j];
將數對根據差值排序
此時
當數對後一個爲x時
取max(dis1[1~x-1])+dis2[x])
x從1~k
取出的最大值,最後與dis1[n]取最小值便可
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> #include<iostream> using namespace std; int n,m,k;const int maxn=2e5+10; int head[maxn*2]; int p[maxn]; int cnt=0; int dis1[maxn],dis2[maxn]; struct node{ int v,next; }e[maxn*2]; void add(int u,int v){ e[++cnt].v=v; e[cnt].next=head[u]; head[u]=cnt; } bool cmp(int a,int b){ return dis1[a]-dis2[a]<dis1[b]-dis2[b]; } void dj(int st,int dis[]){ bool vl[maxn]; memset(vl,0,sizeof(vl)); memset(dis,0x3f3f3f3f,maxn*4); dis[st]=0; priority_queue<pair<int,int> >q; q.push(make_pair(-dis[1],st)); while(!q.empty()){ int u=q.top().second;q.pop(); if(vl[u]) continue; vl[u]=1; for(int i=head[u];i;i=e[i].next){ int v=e[i].v; if(dis[v]>dis[u]+1){ dis[v]=dis[u]+1; q.push(make_pair(-dis[v],v)); } } } } int main(){ scanf("%d%d%d",&n,&m,&k);memset(head,0,sizeof(head)); for(int i=1;i<=k;++i) scanf("%d",&p[i]); for(int i=1;i<=m;++i){ int u,v;scanf("%d%d",&u,&v); add(u,v);add(v,u); } dj(1,dis1); dj(n,dis2); sort(p+1,p+1+k,cmp); int res=0,x=dis1[p[1]]; for(int i=2;i<=k;++i){ int t=p[i]; res=max(res,dis2[t]+x+1); x=max(x,dis1[t]); } printf("%d",min(res,dis1[n]));return 0; }