1. 程式人生 > >每天一套題打卡|河南省第十一屆ACM/ICPC

每天一套題打卡|河南省第十一屆ACM/ICPC

alt int 最小 高度 eid als namespace icpc 分享

A 計劃日

題意:已知李明在YYYY年MM月DD日星期W訂了學習計劃,現在想看看李明N天後的完成情況和個人總結,你能告訴我那天的日期和星期幾嗎?
技術分享圖片

模擬日期計算;
計算星期可以用基姆拉爾森公式

//中國的星期 結果要+1
int Day(int y,int m,int d)
{
    if(m==1 || m==2)  m+=12,y-=1;
    return (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
}

AC代碼

#include<bits/stdc++.h>
using namespace std;

int t;
bool isLeap(int year){
    if(year %4 == 0 && year%100!=0 || year%400== 0){
        return true;
    }
    return false;
}

int main(){
    cin>>t;
    while(t--){
        int year,ta,tb,tc,td,w,n,month,day;
        scanf("%4d%1d%1d%1d%1d %d %d",&year,&ta,&tb,&tc,&td,&w,&n);
        month = ta*10 + tb;
        day = tc*10 + td;
        if(w==7) w=0;

        for(int i=1;i<=n;i++){
            if(month == 12){
                if(day==31){
                    year++;
                    month = 1;
                    day = 1;
                }else{
                    day++;
                }
            }else if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10){
                if(day == 31){
                    month++;
                    day = 1;
                }else{
                    day++;
                }
            }else if(month == 4 || month == 6 || month == 9 || month == 11){
                if(day == 30){
                    month++;
                    day = 1;
                }else{
                    day++;
                }
            }else if(month == 2){
                if(isLeap(year)){
                    if(day == 29){
                        month++;
                        day = 1;
                    }else{
                        day++;
                    }
                }else{
                    if(day == 28){
                        month++;
                        day = 1;
                    }else{
                        day++;
                    }
                }
            }
            w = (w+1)%7;
        }
        printf("%d",year);
        if(month<10){
            printf("0%d",month);
        }else{
            printf("%d",month);
        }
        if(day<10){
            printf("0%d ",day);
        }else{
            printf("%d ",day);
        }
        if(w==0) w = 7;
        printf("%d\n",w);

    }   
    return 0;
} 

B 治安管理

題意:YYH大型活動將在[S,F)這段時間舉行,現要求活動期間任何時刻巡邏的警察人數不少於M人。公安機關將有N名警察在維護活動的安全,每人巡邏時間為[ai,bi)。請你檢查目前的值班安排,是否符合要求。若滿足要求,輸出YES,並輸出某個時刻同時巡邏的最多人數;若不滿足要求,輸出NO,並輸出某個時刻同時巡邏的最少人數。

技術分享圖片

暴力可以過;數據如果再復雜點,可以用差分求解區間問題。

AC代碼

#include<bits/stdc++.h>
using namespace std;


int t;
const int maxn = 1e6+5;
int n,m,s,f;
int p[maxn];
int q[maxn];
int a[maxn];


int main(){
    cin>>t;
    while(t--){
        memset(a,0,sizeof(a));
        memset(p,0,sizeof(p));
        memset(q,0,sizeof(q));
        cin>>n>>m>>s>>f;
        for(int i=1;i<=n;i++) cin>>p[i];
        for(int i=1;i<=n;i++) cin>>q[i];
        for(int i=1;i<=n;i++){
            for(int j=p[i];j<q[i];j++){
                a[j]++;
            }
        }
        int mint = 0x3f3f3f3f;
        int maxt = 0;
        for(int i=s;i<f;i++){
            if(mint >= a[i]) mint = a[i];
            if(maxt <= a[i]) maxt = a[i];
        }
        if(mint == 0x3f3f3f3f) mint = 0;
        if(mint<m)cout<<"NO "<<mint<<endl;
        else cout<<"YES "<<maxt<<endl;
    }
    return 0;
} 

C 山區修路

最近,HB省決定修一條從YC市通往SNJ風景區的高速公路。經過勘測分析,途中需要經過高度分別為H1,H2,……,Hn的N個山區。由於高低不平,除正常的修路開支外,每段還要多出高度差|Hi - Hi-1|*X萬元的斜坡費用。Dr. Kong 決定通過填高一些區域的高度來降低總的費用。當然填高也是需要一些費用的。每填高Y單位,需要付出Y2萬元費用。
你能否幫Dr. Kong做出一個規劃,通過部分填高工程改造,使得總的費用降下來。

技術分享圖片

思路:線性dp,開始想用一維dp,發現一維沒法做啊,前後兩個山區都影響當前狀態。應該用二維dp[i][j] 表示第i個山區在高度為j時的最小費用。

D 求XF+閉包

題意:前面大段都不用看
已知 F 是關系模式R(U)上的函數依賴集,利用Armstrong公理系統可以推導出更多的函數依賴。設X是屬性集U={ A1,A2, ……, An} 的子集, 定義X關於F的閉包XF+

XF+={ Ai | 若X->Ai可以通過Armstrong公理導出}

對於給定的U , F ,X, 請求出XF+

意思就是:若X包含S,就將T加入X

技術分享圖片

思路:我是用字符串string直接做的,string.find()來查找
AC代碼,南陽oj過不了,鄭輕可以過,有時間再補題吧

#include<bits/stdc++.h>
using namespace std;

int t;
set<char> se;

int main(){
    cin>>t;
    while(t--){
        int n,m,k;
        cin>>n>>m>>k;
        string u,x;
        cin>>u;
        cin>>x;
        for(int i=1;i<=k;i++){
            string s;
            string t;
            cin>>s;
            cin>>t;
            bool flag = true;
            int len = s.length();
            for(int j=0;j<len;j++){
                if(x.find(s[j]) == string::npos){
                    flag = false;
                    break;
                }
            }
            int len2 = t.length();
            if(flag){
                x.insert(x.length(),t);
//              cout<<x<<endl; 
            }
        }
        for(int i=0;i<x.length();i++){
            se.insert(x[i]);
        }
        set<char>::iterator it = se.begin();
        while(it!=se.end()){
            cout<<*it;
            it++;
        }
        cout<<endl;
        se.clear();
    }   
    return 0;
} 

E 物流配送

http://nyoj.top/web/contest/problem/cid/103/num/E

聽說是最小費用最大流

但是我沒做過題,想學的時候再補。

F Gene mutation

http://nyoj.top/web/contest/problem/cid/103/num/F
一道簡單英文題
思路1:從X數組出發 枚舉起點,看看x[i] - y[1]的長度下,x數組中是否都包含Y[j] + x[i] - y[1]
思路2:從Y數組出發,枚舉加減的數量,在X中查找,如果存在Y的每一個元素,則記為一種方案。

我用思路2做的沒過,有時間再用思路1做

G Checkpoints

Chinese peacekeepers are going to the town of Kerver to seek Chinese foreign aid engineers.

The military map shows that there are many checkpoints in the war zone. It can be modeled as a directed graph: nodes represent checkpoints , and edges represents the roads. The goal is that the less peacekeepers pass the checkpoints, the safer it will be.

技術分享圖片

技術分享圖片

做ACM的英文題,前幾段落都可以不讀,題意重點在最後兩段。。

這題是求單源點最短路
用dijkstra跑一遍

南陽OJ過不了,鄭輕可以AC。。。有時間再查問題

#include<bits/stdc++.h>
using namespace std;

int t;
int A,B;
const int MAX_N = 105;
const int MAX_M = 100000;
const int inf = 0x3f3f3f3f;
struct edge {
    int v, w, next;
} e[MAX_M];
int p[MAX_N], eid, n,m;
void mapinit() {
    memset(p, -1, sizeof(p));
    eid = 0;
}
void insert(int u, int v, int w) {  // 插入帶權有向邊
    e[eid].v = v;
    e[eid].w = w;
    e[eid].next = p[u];
    p[u] = eid++;
}
void insert2(int u, int v, int w) {  // 插入帶權雙向邊
    insert(u, v, w);
    insert(v, u, w);
}
int dist[MAX_N];  // 存儲單源最短路的結果
bool vst[MAX_N];  // 標記每個頂點是否在集合 U 中
struct node {
    int u;
  int dist;
    node(int _u, int _dist) : u(_u), dist(_dist) {}
    bool operator < (const node &x) const {
        return dist > x.dist;
    }
}; // 記錄點的結構體
bool dijkstra(int s) {
    // 初始化 dist、小根堆和集合 U
    memset(vst, 0, sizeof(vst));
    memset(dist, 0x3f, sizeof(dist));
    priority_queue<node> min_heap;
    dist[s] = 0;
    min_heap.push(node(s, 0));
    while (!min_heap.empty()){
        // 獲取堆頂元素,並將堆頂元素從堆中刪除
        int v = min_heap.top().u;
        min_heap.pop();
        if (vst[v]) {
            continue;
        }
        vst[v] = true;
        // 進行和普通 dijkstra 算法類似的松弛操作
        for (int j = p[v]; j != -1; j = e[j].next) {
            int x = e[j].v;
            if (!vst[x] && dist[v] + e[j].w < dist[x]) {
                dist[x] = dist[v] + e[j].w;
                min_heap.push(node(x, dist[x]));
            }
        }
    }
    return true;
}

int main(){
    cin>>t;
    while(t--){
        cin>>n>>m>>A>>B;
        mapinit();
        for(int i=1;i<=m;i++){
            int u,v;
            cin>>u>>v;
            insert(u,v,1);
        }
        dijkstra(A);
        cout<<dist[B]<<endl;
    }
    return 0;
}

H Attack City and Capture Territory

Who breaks through the last firepower point, he will win the city.

Because of limited weaponry, weapons of each side can only attack one firepower at a time. But they can control whether completely destroy this firepower point or weaken the strength of firepower point.

Liu_B has a strong think-tank. After calculation, he finds out who will attack first , who will more likely win the city .

從最後兩段中理解題意,是一個直接的nim博弈。

技術分享圖片

AC代碼

#include<bits/stdc++.h>
using namespace std;

int t;
int a[1010];
int n;

int main(){
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        int res = 0;
        for(int i=1;i<=n;i++) res^=a[i];
        if(res){
            puts("Liu_B is sure to win.");
        }else{
            puts("Liu_B is not sure to win.");
        }
    }
    return 0;
} 

每天一套題打卡|河南省第十一屆ACM/ICPC