NOIP2017提高组模拟赛4 (总结)
生活随笔
收集整理的這篇文章主要介紹了
NOIP2017提高组模拟赛4 (总结)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
NOIP2017提高組模擬賽4 (總結(jié))
第一題 約數(shù)
設(shè)K是一個(gè)正整數(shù),設(shè)X是K的約數(shù),且X不等于1也不等于K. 加了X后,K的值就變大了,你可以重復(fù)上面的步驟。例如K= 4,我們可以用上面的規(guī)則產(chǎn)生所有的非素?cái)?shù). 可以通過5次變化得到。 24: 4->6->8->12->18->24.現(xiàn)在給你兩個(gè)整數(shù)N 和 M, 求最少需要多少次變化才能到從 N 變到 M. 如果沒法從N變到M,輸出-1.這道題就是很簡(jiǎn)單的bfs,可以觀察到n變化到m是近似成倍增長(zhǎng)的。其實(shí)從最小到最大的變化也就只有30次而已。 #include<cstdio> #include<algorithm> #include<cmath>typedef long long ll;using namespace std;const int maxl=100; const int oo=1e9; const int N=100000; int T,n,m; int op[N+10],ct,ch,f[N+10]; bool uss[N+10];int main() {freopen("a.in","r",stdin);freopen("a.out","w",stdout);scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);for(int i=1;i<=N;i++) f[i]=oo,uss[i]=0;f[n]=0; ct=ch=1; op[ct]=n;while(ch<=ct){if(op[ch]<m && f[op[ch]]<maxl){int i=floor(sqrt(op[ch]));i=(m<op[ch]+i)?m-op[ch]:i;for(;i>=2;i--){if(op[ch]%i==0){if(op[ch]+i<=m && f[op[ch]]+1<f[op[ch]+i]){if(!uss[op[ch]+i]) op[++ct]=op[ch]+i,uss[op[ch]+i]=1;f[op[ch]+i]=f[op[ch]]+1;//printf("%d %d -> %d %d\n",op[ch],f[op[ch]],op[ch]+i,f[op[ch]+i]);}if(i*i!=op[ct]){int yu=op[ch]+op[ch]/i;if(yu<=m && f[op[ch]]+1<f[yu]){if(!uss[yu]) op[++ct]=yu,uss[yu]=1;f[yu]=f[op[ch]]+1;//printf("%d %d -> %d %d\n",op[ch],f[op[ch]],yu,f[yu]);}}}}}uss[op[ch]]=0;ch++;}printf("%d\n",(f[m]!=oo)?f[m]:-1);}return 0; }第二題 警察與小偷
為幫助捕獲在逃的犯人, 警局引進(jìn)了一套新計(jì)算機(jī)系統(tǒng). 系統(tǒng)覆蓋了N 個(gè)城市,有E條雙向的道路。城市標(biāo)號(hào)為1 到N. 犯人經(jīng)常從一個(gè)城市逃到另外一個(gè)城市. 所以警察想知道應(yīng)該在哪里設(shè)置障礙去抓犯人.計(jì)算機(jī)系統(tǒng)需要回答下面兩種類型的問題: 1. 考慮城市A 、B; 如果把連接城市G1和G2的那條公路切斷,逃犯還能從城市A逃到城市B嗎? 2. 考慮三個(gè)城市A、B 、C. 如果把城市C封鎖(則不能從其他進(jìn)入城市C),逃犯還能從城市A逃到城市B嗎? 你的任務(wù)是幫計(jì)算機(jī)系統(tǒng)回答這些提問。(一開始,任意兩個(gè)城市都是可以相互到達(dá)的).這是一道好題,數(shù)據(jù)很大,但邊是雙向的,只是刪一條邊或一個(gè)點(diǎn),而且保證了點(diǎn)兩兩之間是連通的。(這些很重要)那么,可以從dfs序入手,dfs序是一棵樹,其中會(huì)有返祖邊。(如圖)
那我們只需要判斷刪掉的點(diǎn)或邊是否在u到v的路徑上,不在的話,刪了也沒用。(用三次lca處理)。
如果刪的是邊,判斷邊的左右端點(diǎn)是否為一個(gè)塊,(dfn[a]>dfn[b] 且 low[a]≤dfn[b])是的話,刪了還是u,v保持連通的,否則u,v不連通,(必經(jīng)路被刪)
如果刪的是點(diǎn)c。lca---u,v的公共祖先
若c在u->lca的路徑上,則更新uminlow(能到達(dá)的最早的點(diǎn))。
若c在v->lca的路徑上,則更新vminlow(能到達(dá)的最早的點(diǎn))。
判斷uminlow和vminlow都小于c就保證了u,v之間連通。
否則不連通。
第三題 圓桌會(huì)議
有N個(gè)人順時(shí)針圍在一圓桌上開會(huì),他們對(duì)身高很敏感. 因此決定想使得任意相鄰的兩人的身高差距最大值最小. 如果答案不唯一,輸出字典序最小的排列,指的是身高的排列.一道貪心的題目。假設(shè)不是一個(gè)環(huán),而是一條鏈,那該怎么做?很顯然,低-高-低這類是不可能的,因?yàn)榈?低-高肯定比它更優(yōu)。是環(huán)的話,最低-最高這肯定是不行的,因?yàn)樾枰畲蟮淖钚 ?梢钥紤]數(shù)列拆成兩部分(排序后按A5-A3-A1-A2-A4-A6這樣排)。這樣是最優(yōu)的,詳細(xì)證明如下:A5-A3-A1-A2-A4-A6,假設(shè)A4-A6最大,可以改得更優(yōu),A5移過來,變成A3-A1-A2-A4-A5-A6,那么A3-A6比A4-A6跟大,答案肯定不會(huì)優(yōu)。其他情況也差不多。Ai和Ai+1之間肯定改不了(-_-|| 顯然的)。字典序怎么辦?先求出minans,然后放A1,在右側(cè)放A2,判斷A4和當(dāng)前頭的距離是否合法(小于等于minans),不合法的話A3只能放在頭的左側(cè)作為新的頭(不合法的話,再將A3放在右側(cè)的話,A4就沒法放了 放左或放右都會(huì)使最大距離大于minans),合法的話就將A3放在右側(cè),以此類推。 #include<cstdio> #include<algorithm> #include<cstring> #include<cmath>#define imax(a,b) ((a>b)?(a):(b))typedef long long ll;using namespace std;bool cmp(int a,int b) { return (a<b); }int ng,n,d[60],ans,p[60]; int ya[60],yb[60],l1,l2;int main() {freopen("c.in","r",stdin);freopen("c.out","w",stdout);scanf("%d",&ng);while(ng--){scanf("%d",&n); ans=0;for(int i=1;i<=n;i++) scanf("%d",&d[i]);sort(d+1,d+1+n);int w=(n+1)>>1,q=1,cc=w;p[w]=d[1];for(int i=2;i<=n;i++){if((i&1)==0) w+=q; else w-=q;p[w]=d[i];q++;}ans=abs(p[1]-p[n]);for(int i=2;i<=n;i++) ans=imax(ans,abs(p[i]-p[i-1]));l1=1; l2=1;ya[1]=d[1]; yb[1]=d[1];for(int i=2;i<=n;i++){if(abs(d[i+1]-yb[l2])>ans) yb[++l2]=d[i]; else ya[++l1]=d[i];}for(int i=1;i<=l1;i++) printf("%d ",ya[i]);for(int i=l2;i>=2;i--) printf("%d ",yb[i]); printf("\n");}return 0; }考的不怎么好,沒狀態(tài),最后一題想出來但字典序問題沒搞好。爭(zhēng)取在每一次考試中都能不斷進(jìn)步吧!
超越自己,讓自己變得更好 ------------加油,努力
轉(zhuǎn)載于:https://www.cnblogs.com/kekxy/p/7526108.html
總結(jié)
以上是生活随笔為你收集整理的NOIP2017提高组模拟赛4 (总结)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle、MySQL、SqlServ
- 下一篇: Uni-app开发App和插件以后如何开