codeforces round #257 div2 C、D

來源:互聯網
上載者:User

標籤:style   blog   http   color   strong   os   

本來應該認真做這場的,思路都是正確的。


C題,是先該橫切完或豎切完,無法滿足刀數要求,再考慮橫切+豎切(豎切+橫切),

  因為橫切+豎切(或豎切+橫切)會對切割的東西產生交叉份數,從而最小的部分不會儘可能的大。  

         代碼如下,雖然比較長、比較亂,但完全可以壓縮到幾行,因為幾乎是4小塊重複的代碼,自己也懶得壓縮

         注意一點,比如要判斷最小塊的時候,比如9行要分成2份,最小的剩下那份不是9模數2,而應該是4

m/(k+1)<=m-m/(k+1)*k

 

        

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int MAX = 1e6+10;const LL MOD = 1e9+7;LL f[1000];int main() {    LL n,m,k;    //freopen("in.txt", "r", stdin);    while(scanf("%I64d %I64d %I64d",&n,&m, &k)==3) {        if(k > (n+m-2)) { printf("-1\n"); continue;}        LL k1 = k;        LL ans = 0, ans2 = 0;        if(1){            if(k<=(m-1)){              if(m%(k+1)==0)                ans = m/(k+1)*n;              else if(m/(k+1)<=m-m/(k+1)*k) {                ans = m/(k+1)*n;              }              else ans = (m/(k+1)-1)*n;            }            else {                k -= (m-1);                if(n%(k+1)==0)                    ans = n/(k+1);                else if(m/(k+1)<=m-m/(k+1)*k) {                    ans = n/(k+1);                }                else ans = (n/(k+1)-1);            }        }        //printf("%I64d~\n", ans);        swap(n, m);        if(2){            k = k1;            if(k<=(m-1)){              if(m%(k+1)==0) {                ans2 = m/(k+1)*n;              }              else if(m/(k+1)<=m-m/(k+1)*k) {                ans2 = m/(k+1)*n;              }              else ans2 = (m/(k+1)-1)*n;            }            else {                k -= (m-1);                if(n%(k+1)==0)                    ans2 = n/(k+1);                else if(m/(k+1)<=m-m/(k+1)*k) {                    ans2 = n/(k+1);                }                else ans2 = (n/(k+1)-1);            }        }        printf("%I64d\n", max(ans, ans2));    }}



D題

一看題目時就很欣喜,挺有意思的圖論。

一開始的思路是錯的,每次進行鬆弛操作時判斷當前邊是否標記過,從而進行減減操作,這樣考慮忘了後面可能進行了一些更新,從而覆蓋了前面的標記

正確思路:

在每次優先隊列出點的時候,判斷從起點到這個點的最短路有多少是跟K條(train route)是重複的即可

自己需要注意的地方:

1、怎樣記錄最短路的數目

2、當k==Count[u]時候的處理

 3、小細節,第一個節點u,tt與Count[u]都是等於0的

代碼還是挺快的~

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <cmath>#include <queue>#include <stack>#include <map>#include <set>using namespace std;#define clr(x) memset(x,0,sizeof(x))#define fp1 freopen("in.txt","r",stdin)#define fp2 freopen("out.txt","w",stdout)#define pb push_back#define INF 0x3c3c3c3ctypedef long long LL;const int maxn = 4*1e5;bool vis[maxn];struct Edge {int from,to,dist,cnt;};struct Node{    int d,u;    bool operator <(const Node &a) const {        return a.d<d;   //從小到大排序。    }};int n,m,k; //點數和邊數,用n表示,e不能和m衝突vector<Edge> edges;//邊列表vector<int> G[maxn];//每個結點出發的邊編號(從0開始編號)vector<int> qw[maxn];int Count[maxn];bool done[maxn];//是否已永久編號int d[maxn];//s到各個點的距離int p[maxn];//最短路中的上一條邊void init(){    for(int i=0;i<n;i++) G[i].clear();//清空鄰接表    edges.clear();}void addedge(int from,int to,int dist)//如果是無向,每條無向邊需調用兩次addedge{    edges.push_back((Edge){from,to,dist});    int temp=edges.size();    G[from].push_back(temp-1);}void dijk(int s){    clr(Count);    priority_queue<Node> q;    for(int i=0;i<n;i++) d[i]=INF;    d[s]=0;    memset(done,0,sizeof(done));    q.push((Node){0,s});    while(!q.empty()) {        Node x=q.top();        q.pop();        int u=x.u;        if(done[u]) continue;        done[u]=true;        for(int i=0;i<G[u].size();i++) {            Edge &e=edges[G[u][i]];            if(d[e.to]>d[u]+e.dist) {                d[e.to]=d[u]+e.dist;                p[e.to]=G[u][i];                q.push((Node){d[e.to],e.to});                Count[e.to] = 1;            }            else if(d[e.to]==d[u]+e.dist){                Count[e.to] ++;            }        }        int tt = 0;        for(int i = 0;i < qw[u].size();i++){            if(qw[u][i] > d[u]) {                //printf("%d %d %d~\n", u, qw[u][i], d[u]);                int temp = k -1;                k = temp;            }            else if(qw[u][i] == d[u]) tt++;        }        //printf("%d %d %d!\n", u, tt, Count[u]);        if(tt == 0) continue;        else if(tt < Count[u]) {  k -= tt; }        else if(tt == Count[u]) k -= (tt-1);     }}int main(){    //fp1;    while(scanf("%d %d %d", &n, &m, &k) == 3){        int k1 = k;        init();        int u, v, w;        for(int i = 1;i <= m;i++){            scanf("%d %d %d", &u, &v, &w);            u--; v--;            addedge(u, v, w);            addedge(v, u, w);        }        for(int i = m+1;i <= m+k;i++){            scanf("%d %d", &u, &v);            u--;            addedge(0, u, v);            addedge(u, 0, v);            qw[u].pb(v);        }        dijk(0);        printf("%d\n", k1 - k);    }    return 0;}


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.