1. 程式人生 > >【暴力搜尋】【莫隊演算法】【貪心】[Codeforces Round #340 (Div. 2) ]題解報告

【暴力搜尋】【莫隊演算法】【貪心】[Codeforces Round #340 (Div. 2) ]題解報告

A. Elephant

#include <cstdio>
int main(){
    int n;
    scanf("%d", &n);
    printf("%d\n", n/5+int(n%5>0));

    return 0;
}

B. Chocolate

http://codeforces.com/contest/617/problem/B
可以發現對於每一塊巧克力至少有1個,那麼每一次多出1個堅果那麼就有之前那麼多個空位可以選擇,乘上(空位數量+1)就好了,在這裡注意特判全部都是0的情況和記得開long long

#include <cstdio>
#include <cstring> #include <algorithm> #include <iostream> using namespace std; const int MAXN = 100; int s[MAXN+10]; int main(){ int n, sum=0; scanf("%d", &n); for(int i=1;i<=n;i++) scanf("%d", &s[i]), sum+=s[i]; if(!sum){ printf("0\n"); return
0; } int l = 1; while(!s[l]) l++; long long cnt=1, counter=1; for(int i=l;i<=n;i++){ if(s[i]==0) counter++; else{ cnt *= counter; counter = 1LL; } printf("%I64d\n", cnt); return 0; }

C. Watering Flowers

http://codeforces.com/contest/617/problem/C


以第一個圓心列舉半徑然後判斷到第二個圓心的最遠的不屬於第一個圓心的點的距離,住注意特殊處理第一個圓心半徑為0的情況,同時記得開個long long

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 2000;
long long s[MAXN+10][2];
long long PF(long long u){return u*u;}
int main(){
    long long n, x1, x2, y1, y2;
    scanf("%I64d%I64d%I64d%I64d%I64d", &n, &x1, &y1, &x2, &y2);
    long long ans = 0x7fffffffffffffff;
    for(long long i=1;i<=n;i++)
        scanf("%I64d%I64d", &s[i][0], &s[i][1]);
    s[0][0] = x1, s[0][1] = y1;
    for(long long i=0;i<=n;i++){
        long long tmp = PF(s[i][0]-x1)+PF(s[i][1]-y1);
        long long t2 = 0;
        for(int j=1;j<=n;j++)
            if(PF(s[j][0]-x1)+PF(s[j][1]-y1) > tmp)
                t2 = max(t2, PF(s[j][0]-x2) + PF(s[j][1]-y2));
        ans = min(ans, t2+tmp);
    }
    printf("%I64d\n", ans);

    return 0;
}

D. Polyline

http://codeforces.com/contest/617/problem/D
可以通過觀察發現答案其實只有1 2 3三種情況那麼首先可以發現如果任意兩個點在同一條直線上並且另一個點做該直線的垂線的交點在兩個點的兩邊的延長線上(包括端點)那麼之需要1次轉向,否則就需要3次,1次就只有一種情況——三個點在同一條直線上

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int check(int x1, int y1, int x2, int y2){
    return x1 == x2 || y1 == y2;
}
int main(){
    int x1, x2, x3;
    int y1, y2, y3;
    scanf("%d%d", &x1, &y1);
    scanf("%d%d", &x2, &y2);
    scanf("%d%d", &x3, &y3);
    if(check(x1, y1, x2, y2) && check(x1, y1, x3, y3) && check(x2, y2, x3, y3)) printf("1\n");
    else{
        int ans = 3;
        if(check(x1, y1, x2, y2)){
            if(x1 == x2 && (y3 >= max(y1, y2) || y3 <= min(y1, y2)))
                ans = 2;
            if(y1 == y2 && (x3 <= min(x1, x2) || x3 >= max(x1, x2)))
                ans = 2;
        }
        if(check(x1, y1, x3, y3)){
            if(x1 == x3 && (y2 >= max(y1, y3) || y2 <= min(y1, y3)))
                ans = 2;
            if(y1 == y3 && (x2 <= min(x1, x3) || x2 >= max(x1, x3)))
                ans = 2;
        }
        if(check(x2, y2, x3, y3)){
            if(x3 == x2 && (y1 >= max(y3, y2) || y1 <= min(y3, y2)))
                ans = 2;
            if(y3 == y2 && (x1 <= min(x3, x2) || x1 >= max(x3, x2)))
                ans = 2;
        }
        printf("%d\n", ans);
    }

    return 0;
}

E. XOR and Favorite Number

http://codeforces.com/contest/617/problem/E
莫隊演算法的題目,具體內容可以參考莫隊演算法的論文,首先可以知道k=sum[a]^sum[b-1]因為這裡sum[a]^sum[b-1]其實就是b-a之間的xor的值了那麼每一次尋找有沒有匹配的sum,左端點就找對應的右邊的sum值得個數。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int MAXS = 2000000;
const int MAXN = 100000;
int val[MAXN+10], sum[MAXN+10];
long long t2[MAXS+10], t1[MAXS+10];
struct Task{
    int l, r;
    int lid, id;
    long long ans;
}Q[MAXN+10];
bool cmp(const Task &a, const Task &b) {
    if(a.lid == b.lid)
        return a.r < b.r;
    return a.lid < b.lid;
}
bool cmp2(const Task &a, const Task &b) {
    return a.id < b.id;
}
int main(){
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    for(int i=1;i<=n;i++) scanf("%d", &val[i]);
    sum[1] = val[1];
    for(int i=2;i<=n;i++) sum[i] = sum[i-1] ^ val[i];
    int _bit = sqrt(n + 0.5);
    for(int i=1;i<=m;i++)
        scanf("%d%d", &Q[i].l, &Q[i].r), Q[i].lid=(Q[i].l-1)/_bit+1,Q[i].id=i;
    sort(Q+1, Q+1+m, cmp);
    int l=1, r=0;
    long long tmp=0;
    for(int i=1;i<=m;i++){
        while(l < Q[i].l){
            tmp -= t2[k^sum[l-1]];
            t1[sum[l-1]]--;
            t2[sum[l]]--;
            l++;
        }
        while(l > Q[i].l){
            l--;
            t1[sum[l-1]]++;
            t2[sum[l]]++;
            tmp += t2[k^sum[l-1]];
        }
        while(r < Q[i].r){
            r++;
            t1[sum[r-1]]++;
            t2[sum[r]]++;
            tmp += t1[k^sum[r]];
        }
        while(r > Q[i].r){
            tmp -= t1[k^sum[r]];
            t1[sum[r-1]]--;
            t2[sum[r]]--;
            r--;
        }
        Q[i].ans = tmp;
    }
    sort(Q+1, Q+1+m, cmp2);
    for(int i=1;i<=m;i++)
        printf("%I64d\n", Q[i].ans);

    return 0;
}