zoukankan      html  css  js  c++  java
  • [UPC] 2021秋组队17

    A Quality-Adjusted Life-Year

    签到

    B Gwen’s Gift

    C Forest for the Trees

    gcd

    const int maxn=5e5+7;
    const int inf=0x3f3f3f3f;
    ll n,m,t,p,q;
    ll a[2],b[2];
    inline ll gcd(ll a,ll b){   return b?gcd(b,a%b):a;  }
    int main(){
        ll x1,x2,y1,y2;
        n=read();   m=read();
        x1=read();  y1=read();
        x2=read();  y2=read();
        t=gcd(n,m);
        if(t==1){
            printf("Yes");
            return 0;
        }
        p=n/t;  q=m/t;
        if(x1<=p&&y1<=q){
            if(x2>=n-p&&y2>=m-q){
                printf("Yes");
                return 0;
            }
            ll k=x2/p;
            if(x2%p!=0) k++;
            a[0]=k;
            k=y2/q;
            if(y2%q!=0) k++;
            k=min(k,a[0]);
            printf("No
    ");
            printf("%lld %lld",p*k,q*k);    
        }
        else{
            printf("No
    ");
            printf("%lld %lld",p,q);    
        }
    }
    

    D H-Index

    签到 二分

    vector<int> v;
    bool check(int x) {
        int cnt = 0;
        for (int i = v.size() - 1;i >= 0;i--) {
            if (v[i] >= x) cnt++;
            else {
                break;
            }
        }
        return cnt >= x;
    }
    int main() {
        int n; scanf("%d", &n);
        for (int i = 1;i <= n;i++) {
            int x; scanf("%d", &x);
            v.push_back(x);
        }
        sort(v.begin(), v.end());
        int l = 0, r = 1e9;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (check(mid)) l = mid;
            else r = mid - 1;
        }
        cout << l;
        return 0;
    }
    

    E Driving Lanes

    dp
    根据题意,我们知道在弯道的情况下,行走的路程是 s + c ∗ i s + c * i s+ci,其中 i i i表示的是处于第几道,当 c c c大于0的情况下,要使得 i i i尽可能地小,在 c c c小于0的情况下,要使得 i i i尽可能地大,按照贪心的情况,我们可以直接对应 1 1 1, m m m,所以开始可以考虑贪心,但是要注意在变道的过程中,在直线上行驶的过程中也会多产生一部分代价,所以说在这个过程中,不一定是两个极端的车道1,m更优,而可能是在中间某一个车道产生了最优解,所以这里就不能够在使用贪心来解决,这里我们应该考虑用 d p dp dp

    ac_code:

    int n,m,kk,r;
    int a[2007];
    int s[2007],c[2007];
    int dp[307][307];
    int main() {
    	n = read,m = read,kk = read,r = read;
    	r += kk;
    	for(int i=1; i<=n; i++) a[i] = read;
    	for(int i=1; i<n; i++) s[i]=read,c[i]=read;
    	int ans = 0;
    	Clear(dp,0);
    	dp[0][1] = 1;
    	for(int i=1; i<=n; i++) {
    		for(int j=1; j<=m; j++) {
    			if(dp[i-1][j] == 0) continue;
    			int t = dp[i-1][j];
    			for(int k=1; k<=m; k++) {
    				if(a[i] >= abs(k - j) * kk) {
    					if(!dp[i][k]) dp[i][k] = t + abs(k - j) * r + a[i] - abs(k - j) * kk + s[i] + c[i] * k;
    					else dp[i][k] = min(dp[i][k],t + abs(k - j) * r + a[i] - abs(k - j) * kk + s[i] + c[i] * k);
    //					debug(dp[i][k]);
    				}
    			}
    		}
    	}
    	cout << dp[n][1] - 1 << endl;
    	return 0;
    }
    /**
    4 3
    5 2
    10
    10
    10
    10
    4 -1
    4 -1
    4 1
    ->51
    
    
    4 3
    5 2
    10
    10
    10
    10
    10 -3
    10 -3
    10 1
    ->61
    **/
    

    F Treasure Spotting

    计算几何
    重判没了

    G Neighborhood Watch

    问有多少条道路经过了给出的地点,其中起点和终点可以相同

    typedef long long ll;
    int a[200010], R[200010];
    int main() {
        int n, m; scanf("%d%d", &n, &m);
        for (int i = 1;i <= m;i++) {
            int x; scanf("%d", &x);
            a[x] = 1;
        }
        int idx = n + 1;
        for (int i = n;i >= 1;i--) {
            if (a[i] == 0) R[i] = idx;
            else idx = i;
        }
        ll res = 0;
        for (int i = 1;i <= n;i++) {
            if (a[i] == 1) res += n - i;
            else {
                if (R[i] != n + 1) {
                    res += n - R[i] + 1;
                }
            }
        }
        res += m;
        printf("%lld", res);
        return 0;
    }
    

    H Small Schedule

    重判没了

    I Mr. Plow King

    贪心

    ll cal(ll n,ll m) {
        ll ret = 0;
        while(m) {
            ll x = (n - 1) * (n - 2) >> 1;
            if(m > x) {
                ret += x + 1;
                m = x << 1,-- n;
            } else ret += m,-- n,-- m;
        }
        return ret;
    }
    int main() {
        ll n = read,m = read;
        ll ret = 0;
        cout << cal(n,m) << endl;
        return 0;
    }
    /**
     
     
    **/
    

    J Rainbow Road Race

    bfs
    二进制
    假如给每一个颜色一个标号为1<<x,其中x从1->6
    这样一来,就可以转化为求最短路,终止的条件是经过的路径的颜色|(位运算或)之后,值为27-1,而在判断能不能走的时候也可以这样非常巧秒的判断能不能走
    ac_code:

    #define Clear(x,val) memset(x,val,sizeof x)
    ll a[maxn << 1];
    struct node {
        int v,nex,w;
        int col;
    } e[maxn];
    int cnt,head[maxn];
    int get(char c) {
        if(c == 'R') return 1;
        if(c == 'O') return 2;
        if(c == 'Y') return 3;
        if(c == 'G') return 4;
        if(c == 'B') return 5;
        if(c == 'I') return 6;
        if(c == 'V') return 7;
    }
    bool vis[3007][307];
    ll dis[3007][307];
    void init() {
        cnt = 0;
        Clear(head,-1);
    }
    void add(int u,int v,int w,int col) {
        e[cnt].v = v;
        e[cnt].w = w;
        e[cnt].col = 1<<col;
        e[cnt].nex = head[u];
        head[u] = cnt ++;
    }
    struct Node {
        int to;
        ll w;
        int col;
        friend bool operator<(Node a,Node b) {
            return a.w > b.w;
        }
    };
    priority_queue<Node> que;
    int tot[3007][3007];
    int main() {
        int n = read,m = read;
        init();
        char col;
        for(int i=1; i<=m; i++) {
            int u = read,v = read,w = read;
            scanf("%c",&col);
            int c = get(col) - 1;
            add(u,v,w,c);
            add(v,u,w,c);
        }
        que.push({1,0,0});// node 1 the tent
        memset(dis,127 / 3,sizeof dis);
        ll ans = 0;
        int flag = 0;
        while(que.size()) {
            Node frt = que.top();
            que.pop();
            vis[frt.to][frt.col] = true;
            if(frt.col == (1 << 7) - 1 && frt.to == 1) {
                ans = frt.w;
                flag = 1;
                break;
            }
            int u = frt.to;
            for(int i=head[u]; ~i; i=e[i].nex) {
                int to = e[i].v;
                int w = e[i].w;
                int col = e[i].col;
                int jue = col | frt.col;
                if(vis[to][jue]) continue;// conted with node1
                if(w + frt.w < dis[to][jue]) {
                    dis[to][jue] = w + frt.w;
                    que.push({to,w + frt.w,jue});
                }
            }
        }
        assert(flag);
        cout << ans << endl;
        return 0;
    }
    /**
    7 7
    1 2 1 R
    2 3 1 O
    3 4 1 Y
    4 5 1 G
    5 6 1 B
    6 7 1 I
    1 7 1 V
     
     
    8 7
    1 2 1 R
    1 3 1 O
    1 4 1 Y
    1 5 1 G
    1 6 1 B
    1 7 1 I
    1 8 1 V
     
    **/
    
  • 相关阅读:
    记一次由于缓存导致的bug
    3 Task中的一些枚举 创建时候的、continue时候的
    2 Task中的延续和7种阻塞
    1 Task的简单实用
    关于内存溢出遇到的两种情况
    6 Wcf使用Stream传输
    5 wcf双工
    4 WCF中的RPC和OneWay
    3 WCF一些基础铺垫
    什么是三元表达式?“三元”表示什么意思?
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15459786.html
Copyright © 2011-2022 走看看