BAPC2018做题记录

A.

签到题。排序后贪心。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int MAXN = 100000 + 10;
 6 
 7 int n, x;
 8 int a[MAXN];
 9 
10 int main() {
11     ios::sync_with_stdio(false);
12 
13     cin >> n >> x;
14     for (int i = 1; i <= n; ++i)
15         cin >> a[i];
16     
17     sort(a + 1, a + 1 + n);
18 
19     int s = 1;
20     for (int i = 2; i <= n; ++i) {
21         if (a[i - 1] + a[i] > x)
22             break;
23         s++;
24     }
25     cout << s << endl;
26 }
View Code

B.

直接模拟。码农题。

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 100 + 10;

struct Date {
    int month;
    int day;
    bool operator<(const Date& a) const {
        return month == a.month ? day < a.day : month < a.month;
    }
    bool operator==(const Date& a) const {
        return a.month == month && day == a.day;
    }
    int operator-(const Date& a) const {
        const int DAY_PER_MONTH[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        Date A = *this;
        Date B = a;
        int ans = 0;
        bool flg = false;
        if (A < B) {
            swap(A, B);
            flg = true;
        }
        if (A.month == B.month) {
            ans = A.day - B.day;
        } else {
            ans = DAY_PER_MONTH[B.month] - B.day + 1;
            for (int i = B.month + 1; i < A.month; ++i) {
                ans += DAY_PER_MONTH[i];
            }
            ans += A.day - 1;
        }
        if (flg) {
            ans = 365 - ans;
        }
        return ans;
    }
    Date(int m=0, int d=0): month(m), day(d) {}
    Date yesterday() {
        const int DAY_PER_MONTH[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        int m = month;
        int d = day - 1;
        if (d == 0) {
            m--;
            if (m == 0) {
                m = 12;
            }
            d = DAY_PER_MONTH[m];
        }
        return Date(m, d);
    }
} p[MAXN];

int main() {
    ios::sync_with_stdio(false);

    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        string s;
        cin >> s;
        cin >> s;
        p[i] = Date((s[0] - '0') * 10 + (s[1] - '0'),
                (s[3] - '0') * 10 + (s[4] - '0')
            );
    }
    sort(p + 1, p + 1 + n);
    n = unique(p + 1, p + 1 + n) - p - 1;
    Date today = Date(10, 28);
    p[0] = p[n];

    Date ans;
    int cnt = -1;

    for (int i = 1; i <= n; ++i) {
        int dist = p[i].yesterday() - p[i - 1];
        if (dist > cnt) {
            ans = p[i].yesterday();
            cnt = dist;
        } else if (dist == cnt && p[i].yesterday() - today < ans - today) {
            ans = p[i].yesterday();
        }
    }

    cout << (ans.month < 10 ? "0" : "") << ans.month << '-' << (ans.day < 10 ? "0" : "") << ans.day << endl;
}
View Code

C.

枚举体积的因数,即枚举每一组长宽高并更新答案

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,ans=1e9;
 4 int main(){
 5     scanf("%d",&n);
 6     int stp=sqrt(n);
 7     for(int i=1;i<=stp;i++){
 8         if(n%i==0){
 9             int now=n/i;
10             for(int j=1;j<=stp;j++){
11                 if(now%j==0)ans=min(ans,2*(i*j+n/i+n/j));
12             }
13             for(int j=1;j<=i;j++){
14                 if(i%j==0)ans=min(ans,2*(now*j+n/now+n/j));
15             }
16         }
17     }
18     printf("%d\n",ans);
19 } 
View Code

D.

bfs+并查集。如果A和B无法区分,B和C无法区分,则A和C也无法区分。依据这个性质我们可以把无法区分的状态压缩起来用并查集维护。

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 100000 + 10;

int par[MAXN];

struct Intersection {
    int l, r, visible;
} p[MAXN];

struct Node {
    int a, b, step;
    Node(int a=0, int b=0, int s=0): a(a), b(b), step(s) {}
};

int find(int u) { return u == par[u] ? u : par[u] = find(par[u]); }
void merge(int u, int v) {
    u = find(u), v = find(v);
    if (u != v) {
        par[u] = v;
    }
}

int main() {
    ios::sync_with_stdio(false);
    int n, A, B;
    cin >> n >> A >> B;
    for (int i = 0; i < n; ++i)
        par[i] = i;
    for (int i = 0; i < n; ++i) {
        cin >> p[i].l >> p[i].r >> p[i].visible;
    }
    queue<Node> que;
    que.push(Node(A, B, 0));
    while (!que.empty()) {
        int u = que.front().a, v = que.front().b, step = que.front().step;
        que.pop();
        if (find(u) == find(v))
            continue;
        if (p[u].visible != p[v].visible) {
            cout << step << endl;
            return 0;
        }
        merge(u, v);
        que.push(Node(p[u].l, p[v].l, step + 1));
        que.push(Node(p[u].r, p[v].r, step + 1));
    }
    cout << "indistinguishable\n";
}
View Code

 

F.

二分答案,所有获益的方案统计进入利润

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int N=1e5+10;
 5 int n,m,a[N],b[N];
 6 bool ck(LL x){
 7     LL tmp=0;
 8     for(int i=1;i<=n;i++){
 9         if(1ll*a[i]*x-1ll*b[i]>0)tmp+=1ll*a[i]*x-b[i];
10         if(tmp>=m)return 1;
11     }
12     return tmp>=m;
13 }
14 int main(){
15     scanf("%d%d",&n,&m);
16     for(int i=1;i<=n;i++)
17         scanf("%d%d",&a[i],&b[i]);
18     LL L=1,R=3e9,ans;
19     while(L<=R){
20         LL mid=(L+R)>>1;
21         if(ck(mid))ans=mid,R=mid-1;
22         else L=mid+1;
23     }
24     cout<<ans;
25 }
View Code

G.

枚举ABC分别占据哪一段圆环即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=2e5+10;
 4 char s[N];
 5 int numa[N],numb[N],numc[N],a,b,c,n,ans=1e7;
 6 int getans(int pa,int pb,int pc){
 7     int res=0;
 8     res+=a-(numa[pa+a-1]-numa[pa-1]);
 9     res+=b-(numb[pb+b-1]-numb[pb-1]);
10     res+=c-(numc[pc+c-1]-numc[pc-1]);
11     return res;
12 }
13 int main(){
14     scanf("%d",&n);
15     scanf("%s",s+1);
16     for(int i=n+1;i<=n*2;i++)s[i]=s[i-n];
17     for(int i=1;i<=n*2;i++){
18         numa[i]=numa[i-1]+(s[i]=='A');
19         numb[i]=numb[i-1]+(s[i]=='B');
20         numc[i]=numc[i-1]+(s[i]=='C');
21     }    
22     a=numa[n],b=numb[n],c=numc[n];
23     for(int i=1;i<=n;i++){
24         ans=min(ans,getans(i,i+a,i+a+b));
25         ans=min(ans,getans(i,i+a+c,i+a));
26     }
27     printf("%d\n",ans);
28 }
View Code

I.

二分答案+最大流

注意二分答案之后把图上的点按照可达性分成$2^{s}$个本质不同的块,每个块缩成一个点

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=2e5+10;
  4 typedef long long LL;
  5 const LL inf=2e18;
  6 typedef pair<LL,int>pa;
  7 int n,m,s,num[N],iter[N],ss,tt;
  8 int bk[N],tot,first[N],siz[20],pos[20],dep[N];
  9 LL dis[11][N],sm,p[1<<11];
 10 inline int read(){
 11     int t=1,k=0;char c=getchar();
 12     while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();}
 13     while(c>='0'&&c<='9'){k=k*10+c-'0';c=getchar();}
 14     return t*k;
 15 }
 16 struct edge{
 17     int to,next;
 18     LL c;
 19 }e[N*4];
 20 void add(int u,int v,LL d){
 21     e[++tot].next=first[u],first[u]=tot;
 22     e[tot].c=d,e[tot].to=v;
 23 }
 24 void spfa(int x){
 25     dis[x][pos[x]]=0;
 26     queue<int>q;q.push(pos[x]);
 27     while(!q.empty()){
 28         int now=q.front();q.pop();
 29         for(int i=first[now];i;i=e[i].next){
 30             int u=e[i].to;
 31             if(dis[x][u]>dis[x][now]+e[i].c){
 32                 dis[x][u]=dis[x][now]+e[i].c;
 33                 if(!bk[u])bk[u]=1,q.push(u);
 34             }
 35         }
 36         bk[now]=0;
 37     }
 38 }
 39 int bfs(){
 40     memset(dep,-1,sizeof(dep));
 41     queue<int>q;
 42     while(!q.empty())q.pop();
 43     dep[ss]=0;q.push(ss);
 44     while(!q.empty()){
 45         int now=q.front();q.pop();
 46         for(int i=first[now];i;i=e[i].next){
 47             if(e[i].c<=0)continue;
 48             int u=e[i].to;  
 49             if(dep[u]==-1)dep[u]=dep[now]+1,q.push(u);
 50         }
 51     }   
 52     return dep[tt]!=-1;
 53 }
 54 LL dfs(int x,LL flow){
 55     LL f=flow;
 56     if(x==tt)return f;
 57     for(int &i=iter[x];i;i=e[i].next){
 58         int u=e[i].to;
 59         if(e[i].c>0&&dep[u]==dep[x]+1){
 60             LL tmp=dfs(u,min(flow,e[i].c));
 61             e[i].c-=tmp;e[i^1].c+=tmp;flow-=tmp;
 62             if(!flow)return f;
 63         }
 64     }  
 65     return f-flow;
 66 }
 67 LL dinic(){
 68     LL ret=0;
 69     while(bfs()){   
 70         LL f;
 71         memcpy(iter,first,sizeof(iter));
 72         while((f=dfs(ss,inf))>0)ret+=f; 
 73     }
 74     return ret;
 75 }
 76 bool ck(LL x){  
 77     memset(e,0,sizeof(e));
 78     memset(first,0,sizeof(first));
 79     memset(iter,0,sizeof(iter));
 80     memset(p,0,sizeof(p));
 81     tot=1;ss=(1<<s)+11,tt=(1<<s)+12;
 82     for(int i=1;i<=n;i++){
 83         int tmp=0;
 84         for(int j=0;j<s;j++){
 85             if(dis[j+1][i]<=x)tmp|=(1<<j);
 86         }
 87         p[tmp]+=1ll*num[i];
 88     }
 89     for(int i=0;i<(1<<s);i++)
 90         add(ss,i,p[i]),add(i,ss,0);
 91     for(int i=1;i<=s;i++)
 92         add((1<<s)+i,tt,siz[i]),add(tt,(1<<s)+i,0);
 93     for(int i=0;i<s;i++)
 94         for(int j=0;j<(1<<s);j++)
 95             if((1<<i)&j){ 
 96                 add(j,i+(1<<s)+1,inf);add(i+(1<<s)+1,j,0);
 97             }
 98     return dinic()>=sm;
 99 }
100 int main(){
101     scanf("%d%d%d",&n,&m,&s);
102     for(int i=1;i<=n;i++)
103         scanf("%d",&num[i]),sm+=1ll*num[i];
104     for(int i=1,u,v,w;i<=m;i++){
105         u=read();v=read();w=read();
106         add(u,v,w);add(v,u,w);
107     }
108     for(int i=1;i<=s;i++)scanf("%d%d",&pos[i],&siz[i]);
109     for(int i=1;i<=s;i++)
110         for(int j=1;j<=n;j++)dis[i][j]=1e18;
111     for(int i=1;i<=s;i++)spfa(i);    
112     LL L=0,R=2e18,ans;
113     while(L<=R){
114         LL mid=(L+R)>>1;
115         if(ck(mid))ans=mid,R=mid-1;
116         else L=mid+1;
117     }
118     printf("%lld\n",ans);
119 }
View Code

 J.

最大四边形面积。直接套婆罗摩笈多公式

#include <bits/stdc++.h>

using namespace std;

int main() {
    ios::sync_with_stdio(false);

    int a, b, c, d;
    cin >> a >> b >> c >> d;
    double s = (a + b + c + d) / 2.0;
    double sum = sqrt((s - a) * (s - b) * (s - c) * (s - d));
    cout << fixed << setprecision(9) << sum << endl;
}
View Code

 

posted @ 2020-03-18 21:49  uuzhatetree  阅读(268)  评论(0)    收藏  举报