2018.10.17考试
2018.10.17考試總結
1、咒語
(curse.pas/c/cpp)
【題目描述】
亮亮夢到自己來到了魔法城堡, 但一扇巨大的石門阻攔了他通向城堡內的路。正當他沮喪之際,突然發現門上有一處機關,機關上有一張很長的紙條。亮亮拿起紙條的一端,只見上面寫著打開機關的方法: “打開機關需要念動符咒,咒語是一串長為 L 的由 0 和 1 組成的字符串。在這張長紙條上列了 n 個長為 L 的字符串,正確的咒語即是在紛繁的 2^L 種字符串中,與這些紙條上的字符串相異度之和最小,并且在滿足這一條件下,0 的個數最多的字符串。兩個字符串的相異度定義為對應位置不相等的字符對的個數。如‘011’和‘001’的相異度為 1,因為它們有且只有第二個位置上的字符不相等。 ”亮亮拉起紙條,只覺得紙條似乎永遠也拉不完。這上面有著數以萬計的字符串,而每一個字符串的長度也或百或千,以人力看來是無法得到正確的咒語。你能幫幫他,讓他得以進入魔法城堡,一窺其中的奧秘嗎?
【輸入格式】
第一行為一個數字 N 。
接下來的 N 行, 每行為一個長為 L 的 01 字符串。 數據保證 N 個字符串等長。
【輸出格式】
只有一行,是一個長為 L 的字符串 S,即為正確的咒語。
【樣例輸入】
4
01011
01001
01101
10111
【樣例輸出】
01001
【數據規模】
對于 20%的數據,N<=5;
對于 60%的數據,N<=100;
對于 100%的數據,1<=N<=1000,1<=L<=1000。
簡單題,見下
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char s[1010][1010]; int n,k0,k1; int main() {freopen("curse.in","r",stdin);freopen("curse.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;++i)scanf(" %s",s[i]);int len=strlen(s[1]);for(int i=0;i<len;++i){k0=0,k1=0;for(int j=1;j<=n;++j){if(s[j][i]=='1')k1++;else k0++;}if(k0>=k1)printf("0");else printf("1");}return 0; }2、神光
(light.pas/c/cpp)
【題目描述】
亮亮成功地念出了咒語,石門緩緩地自動移開,一道道絢麗的神光從城堡內激射而出。亮亮好奇而又興奮地走入了城堡中,迎面有一座極長的魔法陣。魔法陣可以看作一條直線,它被均勻地分成了 1 000 000 000 個位置,一個位置可以看成是一個格子。有些位置上筑有法壇,一共 N 座。亮亮只有破了眼前的魔法陣,才能繼續前進,而欲破法陣,必須毀掉所有的法壇。亮亮身前有兩根法杖:一根顏色血紅,能發紅色神光,光芒可以籠罩連續 L個位置并摧毀這 L 個位置上所有的法壇,最多使用 R 次;另一根顏色碧綠,能發綠色神光,光芒可以籠罩連續 2L 個位置,并摧毀這 2L 個位置上所有的法壇,最多使用 G 次。法杖的神奇之處在于,L 的值必須由亮亮事先設定好,并且一經設定,便無法更改。亮亮需要在規定的次數下摧毀所有法壇,并且使得 L 最小。
【輸入格式】
第一行三個整數 N, R, G。
第 i (2<=i<=n+1) 行一個整數\(A_i\) ,表示第 i 座法壇的位置。
【輸出格式】
只有一個整數,表示 L 的最小值。
【樣例輸入】
3 1 1
22
1
7
【樣例輸出】
4
【樣例解釋】
亮亮將 L 設為 4,并用紅色神光籠罩 21-24 位置,用綠色神光籠罩 1-8 位置。
【數據規模】
對于 50%的數據,N <= 100;
對于 100%的數據,1 <= N <= 2000,1 <= R, G,\(A_i\)<= 1,000,000,000。
二分加dp
1.R+G>=N時 輸出1
2.先把\(A_i\)從小到大排序,然后二分枚舉L的長度,對于每一個L,先預處理在b[i]表示第i點使用紅法杖最遠到達的點和c[i]表示第i點使用綠法杖最遠到達的點,f[i][j]表示使用i個紅法杖和使用j個綠法杖所能到達的最遠點,可得f[i][j]=max(b[f[i-1][j]+1],c[f[i][j-1]+1])。
3、迷宮
(maze.pas/c/cpp)
【題目描述】
破了魔法陣后,亮亮進入了一座迷宮。這座迷宮叫做“夢境迷宮” ,亮亮只有走出這座迷宮,才能從睡夢中醒來。
夢境迷宮可以用無向圖來表示。它共有 n 個點和 m 條雙向道路,每條道路都有邊權,表示通過這條道路所需的時間,且每條道路可以多次經過。亮亮位于一號點,而出口則是 n 號點。原本,亮亮該找到一條最短路,快速沖出迷宮,然而,夢境迷宮的特殊之處在于,如果沿著最短路到達出口,亮亮就會永遠陷入夢境。因此,亮亮必須尋找一條次短路。次短路的長度須嚴格大于最短路(可以有多條)的長度,同時又不大于所有除最短路外的道路的長度。你的任務,就是編寫一個程序,幫助亮亮找到通向出口的次短路。
【輸入格式】
第一行有兩個整數 n、m,表示迷宮內共有 n 個點,m 條邊。
接下來 m 行,每行三個整數 x、y、z,表示結點 x 和 y 之間連有一條邊權為z 的無向邊。
【輸出格式】
一個整數,表示次短路的長度。
【樣例輸入】
4 4
1 2 2
2 4 4
2 3 3
3 4 4
【樣例輸出】
9
【樣例解釋】
最短路:1 -> 2 -> 4 (長度為 2+4=6)
次短路:1 -> 2 -> 3 -> 4 (長度為 2+3+4=9)
【數據規模】
對于 100%的數據,1 <= n <= 5000,1 <= m <= 100,000。
對于 100%的數據,1 <= z <= 5000,z 表示無向邊的邊長。
嚴格次短路,從點1和點n,分別求一個最短路,枚舉每一條邊,求點1和點n到該路徑兩端的最短距離,每次進行比較比最短路長且比其他路徑短的距離長度。
90分(不知道為啥分這么高的,求最短路,枚舉最短路徑上每一條路消失,再求最短路)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define int long long using namespace std; struct Edge {int u,v,w,nxt; }e[200010]; int head[200010],tot,n,m,dis[5010],vis[5010],hee[5010],haa[5010],hhh=0x7fffffff;; void add(int u,int v,int w) {e[++tot].u=u;e[tot].v=v;e[tot].w=w;e[tot].nxt=head[u];head[u]=tot; } int spfa() {queue<int>q;memset(dis,0x3f,sizeof(dis));memset(vis,0,sizeof(vis));dis[1]=0;q.push(1);while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;if(dis[v]>dis[u]+e[i].w){dis[v]=dis[u]+e[i].w;hee[v]=i;haa[v]=u;if(!vis[v]){vis[v]=1;q.push(v);}}}}return dis[n]; } int spfa2() {queue<int>q;memset(dis,0x3f,sizeof(dis));memset(vis,0,sizeof(vis));dis[1]=0;q.push(1);while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;if(dis[v]>dis[u]+e[i].w){dis[v]=dis[u]+e[i].w;if(!vis[v]){vis[v]=1;q.push(v);}}}}return dis[n]; } signed main() {freopen("maze.in","r",stdin);freopen("maze.out","w",stdout);cin>>n>>m;for(int i=1,u,v,w;i<=m;++i){cin>>u>>v>>w;add(u,v,w);add(v,u,w);hhh=min(hhh,w);}hhh*=2;int k=spfa();int zd=0x3f3f3f3f;int v=n,sd;while(v!=1){sd=hee[v];int cc=e[sd].w;e[sd].w=0x3f3f3f3f;zd=min(spfa2(),zd);e[sd].w=cc;v=haa[v];}if(zd==k)zd+=hhh;cout<<zd<<"\n";return 0; }正解
#include<iostream> #include<queue> #include<cstring> #include<cstdio> using namespace std; const int N=5010; const int INF=0x3f3f3f3f; struct Edge {int v,w,nxt; }e[200100]; int dis1[N],dis2[N],n,m,tot,head[N]; bool vis[N]; void add(int u,int v,int w) {e[++tot].v=v;e[tot].w=w;e[tot].nxt=head[u];head[u]=tot; } void spfa(int s,int *dis) {queue<int>q;memset(vis,0,sizeof(vis));dis[s]=0;vis[s]=1;q.push(s);while(!q.empty()){int u=q.front();q.pop();vis[u]=0;for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;if(dis[v]>dis[u]+e[i].w){dis[v]=dis[u]+e[i].w;if(!vis[v]){vis[v]=1;q.push(v);}}}} } int main() {freopen("maze.in","r",stdin);freopen("maze.out","w",stdout);scanf("%d%d",&n,&m);memset(dis1,0x3f,sizeof(dis1));memset(dis2,0x3f,sizeof(dis2));for(int i=1,u,v,w;i<=m;++i){scanf("%d%d%d",&u,&v,&w);add(u,v,w);add(v,u,w);}spfa(1,dis1);spfa(n,dis2);int ans=INF,tmp;for(int i=1;i<=n;i++)for(int j=head[i];j;j=e[j].nxt){tmp=dis1[i]+dis2[e[j].v]+e[j].w;if(tmp>dis1[n]&&ans>tmp) ans=tmp;}printf("%d\n",ans);return 0; }轉載于:https://www.cnblogs.com/axma/p/9805184.html
總結
以上是生活随笔為你收集整理的2018.10.17考试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WordCount结对项目
- 下一篇: Lesson 008 —— python