NOIP模擬題 2016.9.24 [貪心] [有依賴的揹包問題] [圖論] [spfa或tarjan縮點+DAGdp]
1.排座椅
(seat.pas/c/cpp)
【問題描述】
上課的時候總有一些同學和前後左右的人交頭接耳,這是令小學班主任十分頭疼的一件事情。不過,班主任小雪發現了一些有趣的現象,當同學們的座次確定下來之後,只有有限的D對同學上課時會交頭接耳。同學們在教室中坐成了M行N列,坐在第i行第j列
的同學的位置是(i,j),為了方便同學們進出,在教室中設定了K條橫向的通道,L條縱向的通道。於是,聰明的小雪想到了一個辦法,或許可以減少上課時學生交頭接耳的問題:她打算重新擺放桌椅,改變同學們桌椅間通道的位置,因為如果一條通道隔開了兩個會交頭接耳的同學,那麼他們就不會交頭接耳了。
請你幫忙給小雪編寫一個程式,給出最好的通道劃分方案。在該方案下,上課時交頭接耳的學生對數最少。
【輸入】
輸入檔案seat.in的第一行,有5各用空格隔開的整數,分別是M,N,K,L,D(2<=N,M<=1000,0<=K< M,0<=L< N,D<=2000)。
接下來D行,每行有4個用空格隔開的整數,第i行的4個整數Xi,Yi,Pi,Qi,表示坐在位置(Xi,Yi)與(Pi,Qi)的兩個同學會交頭接耳(輸入保證他們前後相鄰或者左右相鄰)。
輸入資料保證最優方案的唯一性。
【輸出】
輸出檔案seat.out共兩行。
第一行包含K個整數,a1a2„„aK,表示第a1行和a1+1行之間、第a2行和第a2+1行之間、„、第aK行和第aK+1行之間要開闢通道,其中ai< ai+1,每兩個整數之間用空格隔開(行尾沒有空格)。
第二行包含L個整數,b1b2„„bk,表示第b1列和b1+1列之間、第b2列和第b2+1列之間、„、第bL列和第bL+1列之間要開闢通道,其中bi< bi+1,每兩個整數之間用空格隔開(行尾沒有空格)。
【輸入輸出樣例】
seat.in
seat.out
4 5 1 2 3
4 2 4 3
2 3 3 3
2 5 2 4
2
2 4
【輸入輸出樣例解釋】
* *
※
※
+ +
1 2 3 4 5
上圖中用符號*、※、+ 標出了3 對會交頭接耳的學生的位置,圖中3 條粗線的位置表示通
道,圖示的通道劃分方案是唯一的最佳方案。
這道題還好,直接每次貪心找最大值即可,用排序的方法。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int INF=0x3f3f3f3f;
const int maxn = 1005;
int row[maxn];
int column[maxn];
int M,N,K,L,D;
void init()
{
scanf("%d%d%d%d%d",&M,&N,&K,&L,&D);
for(int i=1;i<=D;i++)
{
int x,y,p,q;
scanf("%d%d%d%d",&x,&y,&p,&q);
if(x==p)
{
if(y>q) swap(y,q);
column[y]++;
}
else
{
if(x>p) swap(x,p);
row[x]++;
}
}
}
struct Node
{
int val;
int id;
bool operator < (const Node t) const { return val < t.val; }
};
priority_queue <Node> c,r;
int ans[maxn],top;
void work()
{
for(int i=1;i<M;i++) r.push((Node){row[i],i});
if(K)
{
top=0;
for(int i=1;i<=K;i++) ans[++top]=r.top().id,r.pop();
sort(ans+1,ans+top+1);
for(int i=1;i<top;i++) printf("%d ",ans[i]);
printf("%d",ans[top]);
}
putchar('\n');
for(int i=1;i<N;i++) c.push((Node){column[i],i});
if(L)
{
top=0;
for(int i=1;i<=L;i++) ans[++top]=c.top().id,c.pop();
sort(ans+1,ans+top+1);
for(int i=1;i<top;i++) printf("%d ",ans[i]);
printf("%d",ans[top]);
}
putchar('\n');
}
int main()
{
freopen("seat.in","r",stdin);
freopen("seat.out","w",stdout);
init();
work();
return 0;
}
2.金明的預算方案
(budget.pas/c/cpp)
【問題描述】
金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間金明自己專用的很寬
敞的房間。更讓他高興的是,媽媽昨天對他說:“你的房間需要購買哪些物品,怎麼佈置,
你說了算,只要不超過N 元錢就行”。今天一早,金明就開始做預算了,他把想買的物品分
為兩類:主件與附件,附件是從屬於某個主件的,下表就是一些主件與附件的例子:
主件 附件
電腦 印表機,掃描器
書櫃 圖書
書桌 檯燈,文具
工作椅 無
如果要買歸類為附件的物品,必須先買該附件所屬的主件。每個主件可以有0 個、1
個或2 個附件。附件不再有從屬於自己的附件。金明想買的東西很多,肯定會超過媽媽限
定的N 元。於是,他把每件物品規定了一個重要度,分為5 等:用整數1~5 表示,第5 等
最重要。他還從因特網上查到了每件物品的價格(都是10 元的整數倍)。他希望在不超過N
元(可以等於N 元)的前提下,使每件物品的價格與重要度的乘積的總和最大。
設第j 件物品的價格為v[j],重要度為w[j],共選中了k 件物品,編號依次為j1,
j2,„„,jk,則所求的總和為:
v[j1]w[j1]+v[j2]*w[j2]+ „+v[jk]*w[jk]。(其中為乘號)
請你幫助金明設計一個滿足要求的購物單。
【輸入檔案】
輸入檔案budget.in 的第1 行,為兩個正整數,用一個空格隔開:
N m
(其中N(< 32000)表示總錢數,m(< 60)為希望購買物品的個數。)
從第2 行到第m+1 行,第j 行給出了編號為j-1 的物品的基本資料,每行有3 個非負整
4
3
4
2
1
數
v p q
(其中v表示該物品的價格(v<10000),p表示該物品的重要度(1~5),q表示該物品是主件還是附件。如果q=0,表示該物品為主件,如果q>0,表示該物品為附件,q是所屬主件的編號)
【輸出檔案】
輸出檔案budget.out只有一個正整數,為不超過總錢數的物品的價格與重要度乘積的總和的最大值(<200000)。
【輸入樣例】
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
【輸出樣例】
2200
有依賴的揹包嘛。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int INF=0x3f3f3f3f;
const int maxn = 3205;
const int maxm = 65;
const int D = 5;
int val[maxm][D],cost[maxm][D];
int tot[maxm];
int dp[maxn];
int n,m;
inline void init()
{
scanf("%d%d",&n,&m); n/=10;
for(int i=1;i<=m;i++)
{
int v,p,q;
scanf("%d%d%d",&v,&p,&q); v/=10;
if(!q) val[i][++tot[i]]=p*v,cost[i][tot[i]]=v;
else
{
int now=tot[q];
for(int i=1;i<=now;i++) val[q][++tot[q]]=val[q][i]+v*p,cost[q][tot[q]]=cost[q][i]+v;
}
}
}
int dynamic()
{
for(int i=1;i<=m;i++)
for(int j=n;j>=1;j--)
for(int k=1;k<=tot[i];k++)
if(j-cost[i][k]>=0) smax(dp[j],dp[j-cost[i][k]]+val[i][k]);
return dp[n];
}
int main()
{
freopen("budget.in","r",stdin);
freopen("budget.out","w",stdout);
init();
printf("%d",dynamic()*10);
return 0;
}
3.最優貿易
(trade.pas/c/cpp)
【問題描述】
C國有n個大城市和m條道路,每條道路連線這n個城市中的某兩個城市。任意兩個城市之間最多隻有一條道路直接相連。這m條道路中有一部分為單向通行的道路,一部分為雙向通行的道路,雙向通行的道路在統計條數時也計為1條。
C國幅員遼闊,各地的資源分佈情況各不相同,這就導致了同一種商品在不同城市的價格不一定相同。但是,同一種商品在同一個城市的買入價和賣出價始終是相同的。
商人阿龍來到C國旅遊。當他得知同一種商品在不同城市的價格可能會不同這一資訊之後,便決定在旅遊的同時,利用商品在不同城市中的差價賺回一點旅費。設C國n個城市的標號從1-n,阿龍決定從1號城市出發,並最終在n號城市結束自己的旅行。在旅遊的過程中,任何城市可以重複經過多次,但不要求經過所有n個城市。阿龍通過這樣的貿易方式賺取旅費:他會選擇一個經過的城市邁入他最喜歡的商品——水晶球,並在之後經過的另一個城市賣出這個水晶球。用賺取的差價當作旅費。由於阿龍主要是來C國旅遊,他決定這個貿易只進行最多一次。當然,在賺不到差價的情況下它就無需進行貿易。
假設C國有5個大城市,城市的編號和道路連線情況如下圖,單向箭頭表示這條道路為單向通行。雙向箭頭表示這條道路為雙向通行。
3
1
2
4
5
假設1~n號城市的水晶球價格分別為4,3,5,6,1。
阿龍可以選擇如下一條線路:1->2->3->5,並在2號城市以3的價格買入水晶球,在3號城市以5的價格賣出水晶球,賺取的旅費數為2。
阿龍也可以選擇如下一條線路:1->4->5->4->5,並在第1次到達5號城市時以1的價格買入水晶球,在第2次到達4號城市時以6的價格賣出水晶球,賺取的旅費數為5。
現在給出n個城市的水晶球價格,m條道路的資訊(每條道路所連線的兩個城市的編號以及該條道路的通行情況)。請你告訴阿龍,他最多能賺錢多少旅費。
【輸入】
輸入檔名為trade.in。
第一行包含2個正整數n和m,中間用一個空格隔開,分別表示城市的數目和道路的數目。
第二行n個正整數,每兩個正整數之間用一個空格隔開,按標號順序分別表示這n個城市的商品價格。
接下來m行,每行有3個正整數,x,y,z,每兩個整數之間用一個空格隔開。如果z=1,表示這條道路是城市x到城市y之間的單向道路;如果z=2,表示這條道路為城市x和城市y之間的雙向道路。
【輸出】
輸出檔案trade.out共1行,包含1個整數,表示最多能賺取的旅費。如果沒有進行貿易,則輸出0。
【輸出輸出樣例】
trade.in
trade.out
5 5
4 3 5 6 1
1 2 1
1 4 1
2 3 2
3 5 1
4 5 2
4
【資料範圍】
輸入資料保證1號城市可以到達n號城市。
對於10%的資料,1≤n≤6。
對於30%的資料,1≤n≤100。
對於50%的資料,不存在一條旅遊路線,可以從一個城市出發,再回到這個城市。
對於100%的資料,1≤n≤100000,1≤m≤500000,1≤x,y≤n,1≤z≤2,1≤各城市水晶球價格≤100。
第一種解法,列舉買入賣出分界點,前面找最小值買入後面找最大值賣出,spfa自動處理環了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int INF=0x3f3f3f3f;
const int maxn = 100005;
const int maxm = 500005;
struct Edge
{
int to,next;
}edgeD[maxm<<1],edgeR[maxm<<1];
int headD[maxn],headR[maxn];
int maxedgeD,maxedgeR;
inline void addedge(int u,int v,bool bi_directed)
{
edgeD[++maxedgeD] = (Edge) { v,headD[u] };
headD[u] = maxedgeD;
edgeR[++maxedgeR] = (Edge) { u,headR[v] };
headR[v] = maxedgeR;
if(bi_directed)
{
edgeD[++maxedgeD] = (Edge) { u,headD[v] };
headD[v] = maxedgeD;
edgeR[++maxedgeR] = (Edge) { v,headR[u] };
headR[u] = maxedgeR;
}
}
int val[maxn];
int n,m;
inline void init()
{
scanf("%d%d",&n,&m);
memset(headD,-1,sizeof(headD)); maxedgeD=-1;
memset(headR,-1,sizeof(headR)); maxedgeR=-1;
for(int i=1;i<=n;i++) scanf("%d",val+i);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z-1);
}
}
bool inque[maxn];
int mn[maxn],mx[maxn];
void spfa(int S,bool flag,int dis[maxn]) // flag==true indicates maximum
{
queue <int> que;
for(int i=0;i<=n+1;i++) dis[i]=flag?-INF:INF;
que.push(S); inque[S]=true; dis[S]=val[S];
while(!que.empty())
{
int u=que.front(); que.pop(); inque[u]=false;
for(int i=flag?headR[u]:headD[u];~i;i=(flag?edgeR[i]:edgeD[i]).next)
{
int v=(flag?edgeR[i]:edgeD[i]).to;
if((dis[v]>min(dis[u],val[v]) && !flag) || (dis[v]<max(dis[u],val[v]) && flag))
{
dis[v]=flag?max(dis[u],val[v]):min(dis[u],val[v]);
if(inque[v]) continue;
que.push(v); inque[v]=true;
}
}
}
}
int work()
{
spfa(1,0,mn);
spfa(n,1,mx);
int ret = -INF;
for(int i=1;i<=n;i++) smax(ret,mx[i]-mn[i]);
return ret;
}
int main()
{
freopen("trade.in","r",stdin);
freopen("trade.out","w",stdout);
init();
int ans = work();
printf("%d",max(ans,0));
return 0;
}
第二種解法,Tarjan縮點之後求DAG最短路,用topsort,注意判斷點的可達性。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int INF=0x3f3f3f3f;
const int maxn = 100005;
const int maxm = 500005;
struct Edge
{
int to,next;
}edge[maxm<<1],edgeR[maxm<<1],edgeRR[maxm<<1];
int head[maxn],headR[maxn],headRR[maxn];
int maxedge,maxedgeR,maxedgeRR;
inline void addedge(int u,int v,int bi_directed)
{
edge[++maxedge] = (Edge) { v,head[u] };
head[u] = maxedge;
if(bi_directed)
{
edge[++maxedge] = (Edge) { u,head[v] };
head[v] = maxedge;
}
}
inline void addedgeR(int u,int v)
{
edgeR[++maxedgeR] = (Edge) { v,headR[u] };
headR[u] = maxedgeR;
edgeRR[++maxedgeRR] = (Edge) { u,headRR[v] };
headRR[v] = maxedgeRR;
}
int val[maxn];
int n,m;
namespace Scc
{
int cnt;
int sccno[maxn];
int in[maxn];
bool marked[maxn];
int mn[maxn],mx[maxn];
int dfs_clock,dfn[maxn];
bool insta[maxn];
stack <int> sta;
int dfs(int u)
{
sta.push(u); insta[u]=true;
int lowu=dfn[u]=++dfs_clock;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
int lowv=dfs(v);
smin(lowu,lowv);
}
else if(insta[v]) smin(lowu,dfn[v]);
}
if(lowu>=dfn[u])
{
cnt++;
int tmp;
do
{
tmp=sta.top(); sta.pop(); insta[tmp]=false;
sccno[tmp]=cnt;
smin(mn[cnt],val[tmp]); smax(mx[cnt],val[tmp]);
}while(tmp^u);
}
return lowu;
}
void tarjan()
{
memset(mn,0x3f,sizeof(mn));
dfs(1);
}
}
void mark(int u)
{
Scc::marked[u]=true;
for(int i=headRR[u];~i;i=edgeRR[i].next)
{
int v=edgeRR[i].to;
if(!Scc::marked[v]) mark(v);
}
}
bool vis[maxn];
void get_deg(int u)
{
vis[u]=true;
for(int i=headR[u];~i;i=edgeR[i].next)
{
int v=edgeR[i].to;
Scc::in[v]++;
if(!vis[v]) get_deg(v);
}
}
void init()
{
memset(head,-1,sizeof(head)); maxedge=-1;
memset(headR,-1,sizeof(headR)); maxedgeR=-1;
memset(headRR,-1,sizeof(headRR)); maxedgeRR=-1;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",val+i);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z-1);
}
using namespace Scc;
tarjan();
for(int u=1;u<=n;u++)
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(sccno[u]^sccno[v]) addedgeR(sccno[u],sccno[v]);
}
mark(sccno[n]);
get_deg(sccno[1]);
}
int dis[maxn];
void spfa(int S)
{
using namespace Scc;
memset(dis,0x3f,sizeof(dis));
queue <int> que;
que.push(S); dis[S]=mn[S];
while(!que.empty())
{
int u=que.front(); que.pop();
for(int i=headR[u];~i;i=edgeR[i].next)
{
int v = edgeR[i].to;
if(dis[v]>min(dis[u],mn[v]))
dis[v]=min(dis[u],mn[v]);
if(--in[v]==0) que.push(v);
}
}
}
int main()
{
freopen("trade.in","r",stdin);
freopen("trade.out","w",stdout);
init();
using namespace Scc;
spfa(sccno[1]);
int ans=0;
for(int i=1;i<=cnt;i++) if(marked[i])
smax(ans,mx[i]-dis[i]);
printf("%d",ans);
return 0;
}
相關推薦
NOIP模擬題 2016.9.24 [貪心] [有依賴的揹包問題] [圖論] [spfa或tarjan縮點+DAGdp]
1.排座椅 (seat.pas/c/cpp) 【問題描述】 上課的時候總有一些同學和前後左右的人交頭接耳,這是令小學班主任十分頭疼的一件事情。不過,班主任小雪發現了一些有趣的現象,當同學們的座次確定下來之後,只有有限的D對同學上課時會交頭接耳。同學們在教室
NOIP模擬題 2016.10.6 [並查集] [聯通性] [Tarjan]
T1 ,圖的連通性 題意:給一個圖,支援刪除操作,詢問任意時刻兩個點的連通性 觀察到只有刪除操作,那麼可以考慮倒著處理 先把所有將來會刪除的邊刪掉,然後從最後一組詢問倒著處理 並查集維護連通性 這裡的強制線上是騙人的 在任意時刻圖中剩下的邊數都是可以
9.27考試 SD_le NOIP模擬題 第三題 建造遊樂場題解
closed sin es2017 com 需要 style pla math spl 這道題當時沒讀完題時腦部了無數種問法,然而最後還是猝不及防。一開始還以為是結論題,然而死也退不出來,就先去打第二題了。然後在想這道題時,我想到的是這樣的思路(由於當時時間緊迫,
【NOIP模擬題】【模擬】【DP】【JOI】2016.11.14第一題 複製&貼上2 題解
複製&貼上2(A.c/cpp/pas/in/out) (Time Limit:1s Memory Limit:256MB) 【Description】 文字編輯器的一個最重要的機能就是複製&貼上。JOI社現在正在開發一款能夠非常高速地進行復
【NOIP模擬題】【圖論】2016.11.18 第二題 心 題解
第二題:心(heart.cpp/c/pas) 背景描述: 不是一切深淵都是滅亡 不是一切滅亡都覆蓋在弱者的頭上 ——《這也是一切》 舒婷 有N個透明的盒子, 每個盒子裡面有兩個不同顏色的球,
8.22 NOIP 模擬題
next mil 黑蘋果 blog inux c++ cst mov cpp
NOIP模擬賽(2017.9.15) -餐廳(restaurant)
放下 輸入 機器 代碼 決定 -a scanf 實現 span 餐廳(restaurant) 【問題描述】 小R最近在玩一款模擬餐廳打工的遊戲,其中有一個疊盤子的小遊戲小R很喜歡。這個小遊戲是這樣的:有一個放盤子的機器會在一條直線上運動,機器裏裝著n個盤子,其中第i個盤子半
[BZOJ入門OJ2092][Noip模擬題]舞會
insert top true page sta stat 男女 ble board 2092: [Noip模擬題]舞會 Time Limit: 20 Sec Memory Limit: 256 MB Submit: 9 Solved: 5 [Submit][Stat
七中高新 NOIP模擬題 第二題 上低音號 題
blog image 形狀 位置 行數 noi 完成 noip alt 由於這道題至今無人改掉(其實是沒人想改),我就不去說題解了,只說說我當時考試的思路。 按照套路,先想暴力,很明顯,枚舉矩形形狀再去暴力查詢是人人都想得到的,但是復雜度O(n^4),而數據範圍第
七中高新 NOIP模擬題 第一題 黃金拼圖題解
alt 答案 void 註意 意思 urn 屬於 namespace cst 開始考試時滿心以為不會像上次SD_le出的模擬題一樣不友好,然而我還是太年輕了…… 基本這道題就定了本次考試基本的基調——暴力大賽。 這套題被大佬們譽為“偏難怪”,中的“偏
10.1 國慶節給祖國母親獻禮 NOIP 模擬題 第二題題解
只需要 cpp http i++ bool 兩種 struct 存在 light 2503: 相框 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 108 Solved: 52[Submit][Status][Discuss
noip模擬題 2017.10.28 -kmp -Tarjan -鬼畜的優化
sstream putchar 判斷 cnblogs class break 發現 pop ems 題目大意 給定A串,選擇A串的前lB個字符作為B串,再在B串後增加一個字符,問最長的相等的A串前綴和B串的後綴。 Solution 1(KMP)
[NOIP模擬賽7.9]fseq:卡特蘭數
stdout pen clas 1.0 卡特蘭 c代碼 open -- 就是 卡特蘭數裸題,太裸了。 (可我就是錯了QwQ,忘了特判n<m的情況) AC代碼: #include <cstdio> #include <cstdlib> int n
入門OJ 4192: [Noip模擬題]黑魔法師之門
argv else scan ons scanf nio public lse 代碼 題目 Description applepi被囚禁的地點只有一扇門,當地人稱它為“黑魔法師之門”。這扇門上畫著一張無向無權圖,而打開這扇門的密碼就是圖中【每個點的度數大於零且都是偶數】的子
10.19 noip 模擬題 【NOIP2018模擬賽2018.10.19】
今天也才改出來一道題orz,大坑最近要填,,, 今天題目難度適中,暴力都打出來了,但是第二題“spfa死了”。 於是今天就改出來了第一題和去練了下dijkstra+堆優化。。。於是時間不夠用orz。。 -------------------------------------------
[Noip模擬題]統計方案
題目並不難,想一下就會了,我真的智商持續下降,取模情況下做除法我都沒想到逆元。 總之想到逆元就好寫了,還是\(meet\ in\ the\ middle\)裸題,陣列開不下用\(hash/map\)存一下就好了. 提示: 1、特判\(c==1\)的情況 2、特判\(c>=p\)的情況 #include
Noip模擬題解題報告
Pro 題目連結 Sco 預計得分:100+100+100=300100 + 100 + 100 = 300100+100+100=300 實際得分:100+100+0=200100 + 100 + 0 = 200100+100+0=200 被第三題給虐了,打
noip模擬題 ----飛
本題的空間限制是32MB 可以發現實際上就是要求有多少對線段產生了相交 又因為y軸上是升序,所以就是求產生的序列中,有多少個逆序對 可以發現因為資料生成的方法是有跡可循的,我們可以將值域分塊 每a的長度就是一個塊,可以通過一個塊的貢獻統計其他塊的貢獻,就減少了空間和時間複
2018.10.01 NOIP模擬 卡牌遊戲(貪心)
描述 L最近喜歡上了一個卡片遊戲,遊戲規則是: 2個人一共拿2n張卡片,編號1…2n,每個人n張,然後進行n輪出牌,每輪2個人都打一張牌,,點數大的玩家每次獲1分 L可以預測到對方要打牌的順序。 同時,
NOIP模擬題彙總(加厚版)
$NOIP$模擬題彙總(加厚版) T1 string 描述 有一個僅由 '0' 和 '1' 組成的字串 $A$,可以對其執行下列兩個操作: 刪除 $A$中的第一個字元; 若 $A$中 '1' 出現的次數為奇數,則在 $A$ 的末尾插入 '1',否則在 $A$ 的末尾插入 '0'. 現在給出一個同樣僅由