NOIP2015提高組解析

2021-07-23 17:35:25 字數 3708 閱讀 4712

題目見此

day1

神奇的幻方:

裸裸的模擬(其實也可以發現規律:i+1在i的右上方,如果已經有數了,就填在i的下方)

#include#includeusing namespace std;

int a[50][50];

int nx,ny,n;

int main()else

}elseelse

}} a[tx][ty]=i;

nx=tx;ny=ty;

}//緊跟題目走,比較low的程式

for (int i=1;i<=n;i++)

return 0;

}

資訊傳遞:

當時比賽時用pascal打了個tarjan求強連通分量,不知為什麼爆棧40分,心痛心痛

所以這次打了個簡單的深搜,其實就是沿著走,如果當前的點已經訪問過了就是乙個環。

#include#include#include#include#define maxn 210000

using namespace std;

int a[maxn];

int ans[maxn];

int res=0x7f7f7f7f;

bool vis[maxn];

int n;

void dfs(int x,int k)

int main()

鬥地主:

又是深搜(好像幾年的noip的壓軸題都是倍增和深搜。。)

其實,每次深蒐時只需記錄當前的步數和剩下的牌,對於每乙個狀態首先模擬不打順子的情況最少步數(無需深搜,直接計算),再深搜需要打順子的情況,加個最優化剪枝就行了,不是非常複雜。

#include#include#includeusing namespace std;

int n;

int hand[25];

int sum[25];

int ans;

int unline()

void dfs(int dep)}}

for (int i=2;i<=13;i++) }}

for (int i=2;i<=13;i++) }}

}int main()

ans=0x7f7f7f7f;

dfs(0);

printf("%d\n",ans);

} return 0;

}

day2:

跳石頭:

此題在poj之旅中應做過,二分即可,比賽當時因為r上限取錯了,30分沒了,心痛心痛。

建立模型(l,r]區間,取mid貪心判斷,(貪心:如果當前石頭比上乙個選取剩下的石頭的距離小於mid就把當前石頭移走,最後若移走的石頭數大於m,就說明mid過大,r=mid,否則l=mid。

#include#include#define maxn 110000

using namespace std;

int n,m,l;

int a[maxn];

bool check(int k)

printf("%d",l);

return 0;

}

子串:

其實就是dp,令f[i][j][k]表示a串選到第i個位置(第i個字母要選),b串選到第j個位置,共用了k個子串的方案數

則若a[i]!=b[j]  , f[i][j][k]=0;

a[i]==b[j],f[i][j][k]=f[i-1][j-1][k](和前乙個連成乙個子串)+f[p][j-1][k-1](0

顯然,既超時又超空間。

對於f[p][j-1][k-1]求和,我們預處理sum[i][j-1][k-1]=f[1][j-1][k-1]+.....f[i][j-1][k-1],於是只需o(1)時間轉移,總效率o(nmk)

再發現f[k]只於f[k-1]和sum[k-1]有關,滾動陣列即可。

雖然已滿分,但是顯然很麻煩,

我們重新定義f[i][j][k][0]表示a串選到第i個位置(第i個字母不選),b串選到第j個位置,共用了k個子串的方案數

f[i][j][k][1]表示a串選到第i個位置(第i個字母要選),b串選到第j個位置,共用了k個子串的方案數

原理同上,可推出(t=i&1,p=1-t---->滾動陣列):

f[k][t][j][1]=((f[k-1][p][j-1][0]+f[k-1][p][j-1][1])+f[k][p][j-1][1]);

f[k][t][j][0]=(f[k][p][j][0]+f[k][p][j][1]);

#include#include#includeusing namespace std;

const int maxn=1100;

const int mod=1000000007;

char a[maxn],b[maxn];

int f[210][2][210][2];

int sum=0,n,m,k;

int main()

for (int j=1;j<=m;j++)

for (int k=1;k<=k;k++)

f[k][p][j][0]=f[k][p][j][1]=0;

} printf("%d",(f[k][n&1][m][0]+f[k][n&1][m][1])%mod);

return 0;

}

運輸計畫

此題最好在bzoj上測,其他oj都會爆棧。

顯然直接求最大值不容易,所以我們可以二分結果,取mid

對於一些線路所需時間小於mid的,我們可以不用管,對於大於mid的,應取這些線路的最大公共線段,如果將這一段改為蟲洞仍不能滿足要求,則mid過小,調整區間,反之同理。

但我們還是需要預處理,以1為根建立剖分樹(剖分法求lca),然後求問題中線路起點終點對應的lca和無虫洞時所需的時間,然後就是二分了。

#include#include#include#define maxn 310000

using namespace std;

int cf[maxn],x[maxn],y[maxn];

int dis[maxn],d[maxn],d[maxn],fa[maxn];

int dep[maxn],u[maxn],v[maxn],w[maxn];

int top[maxn],size[maxn],son[maxn];

int a[3*maxn];

int n,m,nodecnt=0;

struct nodee[3*maxn];

void addedge(int u,int v,int w)

void dfs1(int u)

}}void build(int u,int tp)

int lca(int u,int v)

dfs2(1);

return max-redu<=mid;

}int main()

int l=0,r=0;

for (int i=1;i<=m;i++)

while (l>1;

if (check(mid))r=mid;

else l=mid+1;

}printf("%d",l);

return 0;

}

Noip2015提高組總結

總體而言noip還行吧,每天前兩題都穩穩地,但是最後一題做得不好。day1,看完題目後,第一題簽到,第二題很直觀想出來了,又畫了個圖驗證了一下,tarjan雖然可能爆棧,但人工棧就沒問題了。第三題認為是dp一類的東西。畢竟是第一次提高組,還是挺緊張的,一二題打得特別仔細特別慢,對拍,肉眼查錯,搞了接...

NOIP 2015提高組 題解 分析

這一次的提高組出的題挺喪心病狂的,似乎比普及組還要容易看出演算法,隨便就400 我在洛谷上測得好像是500多。真不知ccf在想什麼?算了不說那麼多了,直接上分析 以下的題目中d1a表示第一天第一題,d2b表示第二天第三題,以此類推 題目演算法簡單分析 d1a 簡單模擬 d1b 直接掃一遍找最小環,或...

NOIP2015提高組 跳石頭

問題描述 一年一度的 跳石頭 比賽又要開始了 這項比賽將在一條筆直的河道中進行,河道中分布著一些巨大岩石。組委會已經選 擇好了兩塊岩石作為比賽起點和終點。在起點和終點之間,有 n 塊岩石 不含起點和終 點的岩石 在比賽過程中,選手們將從起點出發,每一步跳向相鄰的岩石,直至到達 終點。為了提高比賽難度...