1. 程式人生 > >NOIP模擬題 2016.9.24 [貪心] [有依賴的揹包問題] [圖論] [spfa或tarjan縮點+DAGdp]

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 [貪心] [依賴揹包問題] [] [spfatarjan+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'. 現在給出一個同樣僅由