Luogu P1311 選擇客棧
阿新 • • 發佈:2018-07-15
ios 循環 兩個 pac class bool isp display 所有
暴力
我一開始做這道題先想到的就是暴力。。。
所以先說一下暴力的做法。首先在輸入的時候講花費小於P的位置標記下來,然後用兩層循環枚舉所有的兩個客棧的組合方案。再用一層循環將兩個客棧之間的位置掃一遍,如果有被標記過得位置證明這種方案是可行的。將其統計下來。
暴力的代碼
#include <iostream> #include <cstring> #include <cstdio> #include <cstring> const int maxn = 2e5+3; const int maxk = 53;暴力using namespace std; int x, f; char c; inline int read() { x = 0, f = 1; c = getchar(); while (c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while (c <= ‘9‘ && c >= ‘0‘) { x = x*10 + c-‘0‘; c = getchar(); }return x * f; } int n, k, p, col[maxn], cost[maxn], Ans; bool book[1003][1003]; int main() { n = read(), k = read(), p = read(); for(int i=1; i<=n; i++) { col[i] = read(); cost[i] = read(); } for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) {for(int k=i; k<=j; k++) { if(cost[k] <= p) { book[i][j] = true; } } } } for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { if(book[i][j] == true && col[i] == col[j]) { Ans++; } } } printf("%d", Ans); }
正解
我們邊輸入邊做處理,考慮用一個cnt[i]表示顏色為i的客棧在當前位置之前有多少個同樣顏色的客棧。用一個now表示最後一家花費小於等於P的咖啡店的位置。再用一個last[i]表示最後一家顏色為i的客棧的位置。顯然,如果last[i]小於等於now,那就說明當前位置上的客棧可以和之前的所有顏色為i的客棧組合,否則就繼續往後掃。重復這些操作,沿途統計有多少種組合
正解的代碼
#include <cstdio> const int maxk = 53; using namespace std; int x, f; char c; inline int read() { x = 0, f = 1; c = getchar(); while (c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while (c <= ‘9‘ && c >= ‘0‘) { x = x*10 + c-‘0‘; c = getchar(); } return x * f; } int n, k, p, now, color, cost, Ans, cnt[maxk], sum[maxk], last[maxk]; int main() { n = read(), k = read(), p = read(); for(int i=1; i<=n; i++) { color = read(); cost = read(); if(cost <= p) now = i; if(now >= last[color]) sum[color] = cnt[color]; Ans += sum[color]; last[color] = i; cnt[color]++; } printf("%d", Ans); }
Luogu P1311 選擇客棧