Time of Update: 2018-12-05
這題也是求逆序數,只是題目描述有點詭異==!給出的是鉤子的id,不是一對一的關係,所以要映射一下,喜歡上用歸併求逆序數#define N 1010int a[N],b[N];int tmp[N];int sum;void merge_sort(int l,int mid,int r){ int i = l,j = mid+1,k = 1; while(i<=mid && j<=r){ if(a[j]<a[i]){
Time of Update: 2018-12-05
很裸的一道二維線段樹,第一次做,其實二維的線段樹也就是樹套樹,先一維再第二維,第一、二維的操作都很類似。說回hdu這道題,有點水,提交的時候記得交c++,g++會wa死你!#define N 210struct node{ int al,ar; double mx;};struct node1{ int hl,hr; node subt[4000];}t[N*4];void build_sub(int id,int rt,int ll,int rr){//第二維建樹
Time of Update: 2018-12-05
建圖:如果有wi < wj , li < lj , and hi < hj ,則j->i連一條有向邊,最後求一次最小路徑覆蓋即可,ps:最小路徑覆蓋 = |V| - 最大匹配#define N 505int match[N];bool vis[N];int g[N][N];int n;struct node{ int w,l,h;}p[N];bool sear(int s){ int i,j; for(i=0;i<n;i++){
Time of Update: 2018-12-05
#define N 101int a[N][N];int dp[N];//費用:天數//價值:a[i][j]//每個課程為一組//組內的天數為一個物品int main(){ int n,m; while(scanf("%d%d",&n,&m) && (n+m)){ int i,j; memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++){ for(j=1
Time of Update: 2018-12-05
今天遇到一題poj2184,大概思路是01背包dp之後把符合要求的最優解統計出來。但是在解01背包的時候遇到一個問題是體積有負數,這樣在dp的過程中會遇到兩個問題:迴圈的時候超出體積的範圍;壓縮空間的時候狀態轉移方程:dp[v]=max(dp[v],dp[v-c[i]]+w[i]),c[i]為負數時v-c[i]>v,這樣按一般的迴圈的方向從大到下會重複計算。先看第二個問題,在一般的01背包壓縮空間的時候,體積的遍曆是從大到小,因為dp[v]=max(dp[v],dp[v-c[i]]+w[i
Time of Update: 2018-12-05
判斷MST時候唯一,用prime演算法,複雜度O(n^2)#define N 105int n,m;int dis[N],g[N][N];bool vis[N];int mx[N][N];//記錄路徑i-j最大的邊值int pre[N];//記錄最小產生樹路徑bool intree[N][N];//判斷哪些邊屬於MSTint prime(int s){ int i,j; for(i=1;i<=n;i++){ dis[i] = g[s][i];
Time of Update: 2018-12-05
首先,我們證明一個結論:樹的重心一定在樹的直徑上樹的直徑指樹上最長的一條路徑,樹的重心指樹上所有點中到其餘點最遠距離最小的點假設重心u不在直徑上,那麼它到距它最遠點(x)的路徑一定會和樹的直徑有交點v,否則這條路徑會是新的直徑的一部分,那麼v到x的距離一定更小,所以重心一定在直徑上顯然,我們需要移走直徑上的一條邊,並且移走這條邊後,原來的樹變成了兩棵樹(特殊情況是移走和葉子相連的一條邊,但不影響)那這樣子,這兩棵樹,每棵樹都有自己的直徑d1,d2,那麼將兩棵樹重新合并後,當前最優解tmp>
Time of Update: 2018-12-05
劉汝佳黑書P89例題,先把邊界入隊,取出最小的檢查4個方向,如果小於當前的證明可以注水,注水完後更新高度為當前高度,入隊;如果大於當前高度就直接入隊。。。所以出隊的元素都是不能注水的....黑書上說有floodfill演算法,沒研究過,應該類似這樣吧LL ans;struct node{ int x,y; int h; friend bool operator < (node a,node b){ return a.h>b.h; }};int
Time of Update: 2018-12-05
最大產生樹,prime演算法改一下就可以了,注意有重邊!!!#define N 1005int g[N][N];int vis[N];int dis[N];int n;int prime(){ int i,j; for(i=1;i<=n;i++){ dis[i] = g[1][i]; vis[i] = 0; } vis[1] = 1; dis[1] = 0; int ans = 0; for(i=2;i<=n;i+
Time of Update: 2018-12-05
簡單的數學題,化簡分數,做法是分別記錄分子和分母的素因子個數,分子的加1,分母的加-1,這樣最後個數為0的就代表已經約去,有個小最佳化,找一個數的素因子的時候用上,快了300ms....Orz,具體看代碼#define N 1000005int max(int a,int b){return a>b?a:b;}LL cnt[N];void gao(int n,int p){ int i; int a=1;
Time of Update: 2018-12-05
擷取機器名<script language=javascript> var WshShell =new ActiveXObject("WScript.Shell"); alert("電腦名稱 = "+ WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%")); alert("登入使用者名稱 = "+
Time of Update: 2018-12-05
簡單的dfs,bfs也可以int g[11][11];int n,m;bool vis[11][11];int d[4][2] = {0,1,0,-1,1,0,-1,0};int ans;void dfs(int x,int y){ if(vis[x][y])return ; vis[x][y] = 1; int i; if(x==1 || y==1 || x==n || y==m) ans++; for(i=0;i<4;i++){
Time of Update: 2018-12-05
容斥原理的應用,分別找1~a的和1~b的個數,相減就是答案,其中找的時候要用容斥原理求,因為有些會重複計數#define N 1000005int p[N];int cnt;void factor(int n){ int i; int a = 1; for(i=2;i*i<=n;i+=a,a=2){ if(n%i==0){ p[cnt++] = i; while(n%i==0){ n/
Time of Update: 2018-12-05
類比不解釋int a[110];int main(){ int t; scanf("%d",&t); int ca = 1; while(t--){ int n; scanf("%d",&n); int i,j; for(i=1;i<=n;i++)scanf("%d",&a[i]); int win = 0; i = 1,j = n;
Time of Update: 2018-12-05
咋一看,Manhattan Sort?納尼?其實水題一道...運用了貪心,因為要總的移動的距離最小的最優辦法就是直接把它挪到它應該放的地方,況且每個數都是唯一的struct node{ int id; int v;}p[33];bool cmp(node a,node b){ return a.v<b.v;}int main(){ int t; scanf("%d",&t); int ca=1; while(t--){
Time of Update: 2018-12-05
跟POJ 1185炮兵陣地差不多int g[16][16];int st[1001];char str[101];int dp[16][(1<<15)];int num[16][1001];int n;int tot;bool ok(int x){ if(x & (x<<1))return 0; if(x & (x>>1))return 0; return 1;}void init(){ tot = 0; int
Time of Update: 2018-12-05
一開始理解錯題意,以為每個人各自有一堆,後來發現是總共才有1堆,問誰會使得堆的和大於31就是輸,可以看出31是必勝點,每個人最優的策略是使得自己到達31,因此可以dfs,利用回溯把每個狀態輸贏求出來,類似於dp,從後往上推。狀態的話可以用一個七維數組記錄char str[200];int dp[33][5][5][5][5][5][5];int num[10];int lin(int sum,int s1,int s2,int s3,int s4,int s5,int s6){
Time of Update: 2018-12-05
erase函數的原型如下:(1)string& erase ( size_t pos = 0, size_t n = npos );(2)iterator erase ( iterator position );(3)iterator erase ( iterator first, iterator last );也就是說有三種用法:(1)erase(pos,n);
Time of Update: 2018-12-05
左邊交點從小到大排序,右邊求逆序數,用歸併求,注意要處理一下左邊交點共點的情況,答案就是直線數+交點數+1,一不小心刷到rank2...ORZ#define N 30005struct node{ int l,r;}p[N];int a[N];int n;int tmp[N];int num;void merge_sort1(int l,int mid,int r) { int k = 1; int i = l,j = mid+1; while(i<=mid
Time of Update: 2018-12-05
dfs。只標記空格int g[22][22];bool vis[22][22];int d[4][2] = {0,1,0,-1,1,0,-1,0};int n;int sumb,sumw,sum;int tag;void dfs(int x,int y){ int i,j; for(i=0;i<4;i++){ int xx = x+d[i][0]; int yy = y+d[i][1]; if(xx<1 || yy<1 ||