10-18考试记
10-18考試記
300分。開(kāi)心。
1、咒語(yǔ)
【題目描述】
亮亮夢(mèng)到自己來(lái)到了魔法城堡,但一扇巨大的石門阻攔了他通向城堡內(nèi)的路。
正當(dāng)他沮喪之際,突然發(fā)現(xiàn)門上有一處機(jī)關(guān),機(jī)關(guān)上有一張很長(zhǎng)的紙條。
亮亮拿起紙條的一端,只見(jiàn)上面寫(xiě)著打開(kāi)機(jī)關(guān)的方法:“打開(kāi)機(jī)關(guān)需要念動(dòng)
符咒,咒語(yǔ)是一串長(zhǎng)為 L 的由 0 和 1 組成的字符串。在這張長(zhǎng)紙條上列了 n 個(gè)
長(zhǎng)為 L 的字符串,正確的咒語(yǔ)即是在紛繁的 2^L 種字符串中,與這些紙條上的
字符串相異度之和最小,并且在滿足這一條件下,0 的個(gè)數(shù)最多的字符串。兩個(gè)
字符串的相異度定義為對(duì)應(yīng)位置不相等的字符對(duì)的個(gè)數(shù)。如‘011’和‘001’的
相異度為 1,因?yàn)樗鼈冇星抑挥械诙€(gè)位置上的字符不相等。”
亮亮拉起紙條,只覺(jué)得紙條似乎永遠(yuǎn)也拉不完。這上面有著數(shù)以萬(wàn)計(jì)的字符
串,而每一個(gè)字符串的長(zhǎng)度也或百或千,以人力看來(lái)是無(wú)法得到正確的咒語(yǔ)。你
能幫幫他,讓他得以進(jìn)入魔法城堡,一窺其中的奧秘嗎?
【輸入格式】
第一行為一個(gè)數(shù)字 N 。
接下來(lái)的 N 行,每行為一個(gè)長(zhǎng)為 L 的 01 字符串。數(shù)據(jù)保證 N 個(gè)字符串等長(zhǎng)。
【輸出格式】
只有一行,是一個(gè)長(zhǎng)為 L 的字符串 S,即為正確的咒語(yǔ)。
記錄每一位有多少個(gè)1就行了。
code:
#include <iostream> #include <cstdio> #include <cstring>using namespace std;const int wx=3017;inline int read(){int sum=0,f=1; char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}return sum*f; }char c[wx][wx]; int l[wx]; int n;//l[i]表示i這一位有多少個(gè)1 //如果這一位的1個(gè)數(shù)多于0,那么這一位答案為1 //否則為0 //暴力打不出來(lái)。。。//SB吧打啥暴力 int main(){freopen("curse.in","r",stdin);freopen("curse.out","w",stdout);n=read();for(int i=1;i<=n;i++)scanf("%s",c[i]+1);int len=strlen(c[1]+1);for(int i=1;i<=n;i++){for(int j=1;j<=len;j++){if(c[i][j]=='1')l[j]++;}} for(int i=1;i<=len;i++){if(l[i]<=(n-l[i]))printf("0");else printf("1");}fclose(stdin);fclose(stdout);return 0; }2、神光
【題目描述】
亮亮成功地念出了咒語(yǔ),石門緩緩地自動(dòng)移開(kāi),一道道絢麗的神光從城堡內(nèi)
激射而出。亮亮好奇而又興奮地走入了城堡中,迎面有一座極長(zhǎng)的魔法陣。
魔法陣可以看作一條直線,它被均勻地分成了 1 000 000 000 個(gè)位置,一個(gè)位
置可以看成是一個(gè)格子。有些位置上筑有法壇,一共 N 座。亮亮只有破了眼前
的魔法陣,才能繼續(xù)前進(jìn),而欲破法陣,必須毀掉所有的法壇。
亮亮身前有兩根法杖:一根顏色血紅,能發(fā)紅色神光,光芒可以籠罩連續(xù) L
個(gè)位置,并摧毀這 L 個(gè)位置上所有的法壇,最多使用 R 次;另一根顏色碧綠,
能發(fā)綠色神光,光芒可以籠罩連續(xù) 2L 個(gè)位置,并摧毀這 2L 個(gè)位置上所有的法
壇,最多使用 G 次。
法杖的神奇之處在于,L 的值必須由亮亮事先設(shè)定好,并且一經(jīng)設(shè)定,便無(wú)
法更改。亮亮需要在規(guī)定的次數(shù)下摧毀所有法壇,并且使得 L 最小。
【輸入格式】
第一行三個(gè)整數(shù) N, R, G。
第 i (2<=i<=n+1) 行一個(gè)整數(shù)Ai,表示第 i 座法壇的位置。
【輸出格式】
只有一個(gè)整數(shù),表示 L 的最小值。
發(fā)現(xiàn)數(shù)據(jù)里的線索 縮小一下DP就可以了。
這個(gè)DP的思路還是不錯(cuò)的。
code:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using namespace std;const int wx=3017;inline int read(){int sum=0,f=1; char ch=getchar();while(ch<='0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}return sum*f; }int pos[wx],f[wx][wx]; int rr[wx],gg[wx]; int n,R,G,ans;//二分? //這數(shù)據(jù)范圍真TM神了 //不太對(duì),R+G>N直接有解1完事。 //OK DP+二分吧 bool ok(int L){memset(f,0,sizeof f);memset(rr,0,sizeof rr);memset(gg,0,sizeof gg);rr[n+1]=n; gg[n+1]=n;for(int i=1;i<=n;i++){rr[i]=upper_bound(pos+1,pos+1+n,pos[i]+L-1)-pos-1;gg[i]=upper_bound(pos+1,pos+1+n,pos[i]+L*2-1)-pos-1;}for(int i=0;i<=R;i++){for(int j=0;j<=G;j++){if(i)f[i][j]=max(f[i][j],rr[f[i-1][j]+1]);if(j)f[i][j]=max(f[i][j],gg[f[i][j-1]+1]);}}if(f[R][G]==n)return true;return false; }int main(){freopen("light.in","r",stdin);freopen("light.out","w",stdout);n=read();R=read();G=read();for(int i=1;i<=n;i++)pos[i]=read();if(R+G>n){puts("1");return 0;}sort(pos+1,pos+1+n);int l=1; int r=pos[n]-pos[1]+1;while(l<=r){int mid=l+r>>1;if(ok(mid))ans=mid,r=mid-1;else l=mid+1;}printf("%d\n",ans);fclose(stdin);fclose(stdout);return 0; } /* 2zz3 2zz3 3zz3 1zz2 2zz2 3zz3 1zz1 2zz2 3zz3 1zz1 2zz2 3zz3 1zz2 2zz2 3zz3 */3、迷宮
【題目描述】
破了魔法陣后,亮亮進(jìn)入了一座迷宮。這座迷宮叫做“夢(mèng)境迷宮”,亮亮只
有走出這座迷宮,才能從睡夢(mèng)中醒來(lái)。
夢(mèng)境迷宮可以用無(wú)向圖來(lái)表示。它共有 n 個(gè)點(diǎn)和 m 條雙向道路,每條道路
都有邊權(quán),表示通過(guò)這條道路所需的時(shí)間,且每條道路可以多次經(jīng)過(guò)。亮亮位于
一號(hào)點(diǎn),而出口則是 n 號(hào)點(diǎn)。原本,亮亮該找到一條最短路,快速?zèng)_出迷宮,然
而,夢(mèng)境迷宮的特殊之處在于,如果沿著最短路到達(dá)出口,亮亮就會(huì)永遠(yuǎn)陷入夢(mèng)
境。因此,亮亮必須尋找一條次短路。次短路的長(zhǎng)度須嚴(yán)格大于最短路(可以有
多條)的長(zhǎng)度,同時(shí)又不大于所有除最短路外的道路的長(zhǎng)度。
你的任務(wù),就是編寫(xiě)一個(gè)程序,幫助亮亮找到通向出口的次短路。
【輸入格式】
第一行有兩個(gè)整數(shù) n、m,表示迷宮內(nèi)共有 n 個(gè)點(diǎn),m 條邊。
接下來(lái) m 行,每行三個(gè)整數(shù) x、y、z,表示結(jié)點(diǎn) x 和 y 之間連有一條邊權(quán)為
z 的無(wú)向邊。
兩邊Dij,再枚舉邊就可以了。
code:
#include <iostream> #include <cstdio> #include <queue>#define int long longusing namespace std;const int wx=500177;inline int read(){int sum=0,f=1; char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}return sum*f; }int n,m,ans=0x7fffffff; int num; int head[wx],diss[wx],dist[wx],vis[wx];struct e{int nxt,to,dis; }edge[wx*2];void add(int from,int to,int dis){edge[++num].nxt=head[from];edge[num].to=to;edge[num].dis=dis;head[from]=num; }struct node{int u,d;friend bool operator < (const node & a,const node & b){return a.d>b.d;} };priority_queue<node > q;void Dijs(){for(int i=1;i<=n;i++)diss[i]=0x7fffffff,vis[i]=0;q.push((node){1,0});diss[1]=0;while(q.size()){int u=q.top().u; q.pop();if(vis[u])continue; vis[u]=1;for(int i=head[u];i;i=edge[i].nxt){int v=edge[i].to;if(diss[v]>diss[u]+edge[i].dis){diss[v]=diss[u]+edge[i].dis;q.push((node){v,diss[v]});}}} }void Dijt(){for(int i=1;i<=n;i++)dist[i]=0x7fffffff,vis[i]=0;q.push((node){n,0});dist[n]=0;while(q.size()){int u=q.top().u; q.pop();if(vis[u])continue; vis[u]=1;for(int i=head[u];i;i=edge[i].nxt){int v=edge[i].to;if(dist[v]>dist[u]+edge[i].dis){dist[v]=dist[u]+edge[i].dis;q.push((node){v,dist[v]});}}} }void work(){int beg=diss[n];for(int u=1;u<=n;u++){for(int i=head[u];i;i=edge[i].nxt){int v=edge[i].to;int tmp=diss[u]+dist[v]+edge[i].dis;if(tmp>beg&&tmp<ans)ans=tmp;}} }//。。。T3是傻逼題 signed main(){freopen("maze.in","r",stdin);freopen("maze.out","w",stdout);n=read(); m=read();for(int i=1;i<=m;i++){int x,y,z;x=read(); y=read(); z=read();add(x,y,z); add(y,x,z);}Dijs();Dijt();work();printf("%lld\n",ans);fclose(stdin);fclose(stdout);return 0; }繼續(xù)加油。
轉(zhuǎn)載于:https://www.cnblogs.com/wangxiaodai/p/9809301.html
總結(jié)
- 上一篇: css3布局篇(双飞翼)
- 下一篇: svn 修改文件的可执行权限