Time of Update: 2018-12-06
http://poj.org/problem?id=2676單純的dfs,用三個數組記錄行、列以及3×3方格的情況。 只是一開始不知道為什麼沒辦法結束程式的運行,提交兩次TLE,感覺應該是getchar()的問題。code:#include<cstdio>#include<iostream>#include<cstring>using namespace std ;bool c[10][10] ;bool r[10][10] ;bool s[4][4][10]
Time of Update: 2018-12-06
http://acm.timus.ru/problem.aspx?space=1&num=1180簡單推理博弈。觀察每次要取的個數,1,2,4,8,16...,對3的餘數分別為1,2,1,2,1...,也就是說,沒有可能只用一次操作從一個3的倍數達到另一個3的倍數。當n=3時,顯然先手必勝,那麼先手只要在第一次操作上使剩餘石子個數為3的倍數即可。這裡先手必敗的情況只有一種,即n%3==0。如何求n%3?一個貌似初中或小學就學過的但是大多數人都忘記的東西:對一個數的每一位累加,結果對3的餘
Time of Update: 2018-12-06
http://poj.org/problem?id=3080給定n個字串,求最長公用子串。利用KMP是對子串從1..j匹配母串,枚舉第一個母串的所有尾碼子串,在KMP匹配過程中得到j的最大值(這裡不能完全符合後再得最大值,為了確保取到所有子串),對n-1個母串匹配完成後,j最大值的最小值便為公用子串。若有多個這樣的子串,字典順序小者為result。這裡用到了string的兩個函數,strcpy(substr, str)和strncpy(substr, str, n)。前者是複製到Null
Time of Update: 2018-12-06
題意: 隨意給定一串數字1,2,3,求最少多少次交換操作可以將其按升序排列,輸出最少次數以及每次交換的位置。代碼:#include<iostream>#include<cstring>using namespace std ;int min(int a, int b){ if(a>b) return b ; else return a ;}int main(){ int n, i, j ; int a[1001], b[1001],
Time of Update: 2018-12-06
Description 73 88 1 02 7 4 44 5 2 6 5(Figure 1)Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can
Time of Update: 2018-12-06
http://poj.org/problem?id=1704把數組倒置(17 14 12 9 7 6 5 1),將相鄰棋子的間距視為一堆石子(2 1 2 0 0 3),那麼題中所給操作即為把後一堆石子中的n個放到前一堆石子中,這樣就轉化為了階梯博弈。用階梯博弈的解法直接奇位異或就ok了。在其他部落格裡還看到一種解法,從後向前兩兩分組,奇數個點則在最前加一個0結點。把兩個結點間的間距看作一堆石子。1. 若對手移動兩個中的前一個,那麼後一個一定可以移動同樣多的位置2.
Time of Update: 2018-12-06
http://poj.org/problem?id=1564 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1711 簡單深搜,主要是這一句if(!vis[i]&&data[i]<=sum&&(data[i]!=data[i-1]||i==pos))。確保兩個連續的相同的數只有一次機會進入ans[],避免了結果的重複。code:#include<cstdio>#incl
Time of Update: 2018-12-06
http://poj.org/problem?id=1611簡單入門並查集, 以前已經做過,但是代碼不太好。DP最佳化搞上火了,做做別的換換腦子...以前代碼 Memory: 356KTime: 32MS #include<cstdio>usingnamespace std;const int maxn = 30000;int father[maxn+5];//記錄父節點int len[maxn+5];//記錄以該點為根的集合元素的個數void init(int n){//並查集的初
Time of Update: 2018-12-06
http://acm.hdu.edu.cn/showproblem.php?pid=1907Nim的變形,最後取為敗,詳見http://www.cnblogs.com/tanky_woo/archive/2010/08/20/1804464.html中取火柴遊戲2。這裡總結下結論:1. 當所有堆個數都為1時,若為奇數堆,即異或不為0,則先手敗,反之先手勝。2. 非所有堆個數都為1時,則異或不為0先手勝。用上述博文中的定義則為T0, S1, S2為必勝態,T1,
Time of Update: 2018-12-06
http://poj.org/problem?id=2524依舊簡單並查集,拿1611火速改了改火速提交,果斷PE...把輸出的最後一個空格放%d前面了,真活該不運行就交。但是這題有個疑問,為什麼按秩合并沒有比直接合并快??code: #include<cstdio>int p[50005], r[50005] ;void make_set(int n){ for(int i=0; i<n; i++){ p[i] = i ; r[i] = 0
Time of Update: 2018-12-06
http://acm.hdu.edu.cn/showproblem.php?pid=4198今天杭電熱身賽的B題,讀完題就上手寫dfs,結果爆棧了,500*500的規模對暴力遞迴來說有點多。然後就是bfs,遇到@時先放入另一隊列,噹噹前step>que[head].step時que[head]入隊(這裡可以證明que[head]的step是que總的最小值)。第一個出口便為最終解。思路就這樣,結果寫出來各種bug各種蛋疼。最後直接調暈了...code:#include<cstdio&
Time of Update: 2018-12-06
http://acm.hdu.edu.cn/showproblem.php?pid=1847和toj1180完全一樣的題。用sg函數寫一下。將1000內的sg值打表即可。code:/*#include<cstdio>int main(){ int n ; while(~scanf("%d", &n)){ if(n%3) printf("Kiki\n") ; else printf("Cici\n") ; } retur
Time of Update: 2018-12-06
http://acm.hdu.edu.cn/showproblem.php?pid=1272裸的並查集,注意兩個地方: 1.最後所有的點要在同一個集合中2.輸入只有0
Time of Update: 2018-12-06
http://acm.hdu.edu.cn/showproblem.php?pid=1536計算sg值。注意兩個地方:1. s是無序的。2. 不能對n=10000打表,因為能取的個數是給定的,會有打不到的點。code:#include<cstdio>#include<cstring>int s[101], sg[10001], k ;int mex(int n){ if(sg[n]!=-1) return sg[n] ; bool vis[101] ;//
Time of Update: 2018-12-06
http://acm.hdu.edu.cn/showproblem.php?pid=3980求sg值。一開始被第二個範例卡住了,讀了好幾遍題才發現它初始是個環。這樣就可以先把它變成鏈,然後在鏈上枚舉取m個連續點,每次都可以將這條鏈分成兩部分,相當於兩個子遊戲。對於一個鏈,一共有n-m-i個子遊戲對,用vis數組標記好這些子遊戲對的異或值,最後就可以找出sg[n]。這算是我做的第三種類型求sg值的題吧。code:#include<cstdio>#include<cstring&g
Time of Update: 2018-12-06
http://poj.org/problem?id=3126給兩個素數,求第一個素數轉變成第二個素數所需最小步驟數。每次轉換隻能改變一位,且轉換的中間數都為素數。最短路徑問題,打出一個素數表,對4位元的各個位置0..9暴搜。比較鬱悶的是sqrt()和pow()中必須要用強制轉換才行,不記得以前要這樣用啊??CE了幾次。code:#include<cstdio>#include<cmath>#include<cstring>using namespace std
Time of Update: 2018-12-06
http://acm.hdu.edu.cn/showproblem.php?pid=1166最基礎的線段樹,單點更新。完全跟著HH的代碼風格寫的。code:#include<cstdio>#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1const int maxn = 50005 ;int sum[maxn<<2] ;void PushUp(int rt){ sum[rt] = sum[
Time of Update: 2018-12-06
http://acm.hdu.edu.cn/showproblem.php?pid=1754基礎線段樹,單點替換,區間最值。code:#include<cstdio>#include<algorithm>using namespace std ;#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1const int maxn = 200010 ;int sum[maxn<<2] ;te
Time of Update: 2018-12-06
DescriptionYou want to arrange the window of your flower shop in a most pleasant way. You have F bunches of flowers, each being of a different kind, and at least as many vases ordered in a row. The vases are glued onto the shelf and are numbered
Time of Update: 2018-12-06
題意: 給定兩個字串,求經過多少次的增刪改操作可使兩個字串相同。與poj2192相似,用dp[n]記錄使str1前n個字元與str2前m個字元相同的最少運算元。每次的判斷都有三種情況,即str1前i個字元str2前j-1個字元,str1前i-1個字元str2前j個字元,str1前i-1個字元str2前j-1個字元。取三種情況經過本次操作後的最小值即可。 代碼:#include<iostream>#include <cstring>using namespace