codeforces-1163 (div2)

想开div3开成div2了,比赛的时候还以为我又菜了。

赛后经验:关爱视力 从我做起

 

A.删除第一个点的时候断环成链,不产生贡献,后面每隔一个拆一个点都会让联通块最终答案 + 1

没有可以产生贡献的点的时候就需要删联通块,此时产生反向贡献答案 - 1

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int main(){
    Sca2(N,M);
    if(!M){
        puts("1");
        return 0;
    } 
    N--; M--;
    int ans = 1;
    for(int i = 2; i < N ; i += 2){
        if(M){
            M--;
            ans++;
        }
    }
    if(M){
        if(N % 2 == 0) M--;
    }
    ans -= M;
    Pri(ans);
    return 0;
}
A

 

B1 B2. 考虑从左往右不断加入数更新答案

用num[maxn]维护这个数字出现的次数,num2[maxn]维护出现了这个次数的数字有多少

答案的产生有如下三种情况。

1.加入的数a[i]是要被删除的数,那么这个数之前的所有数应当有相同的数目,随手取一个a[i - 1],就有num2[num[a[i - 1]]] * num[a[i - 1]] == i - 1的情况下成立

2.加入的数不是要被删除的数,那么显然如果成立.num[a[i]]将会是前面所有的数字出现的次数,check一下num2[num[a[i]]] * num[a[i]] == i - 1的情况是否成立

3.加入的数不是要被删除的数,且有一种数出现了num[a[i]] + 1次,删除掉这种数的一个数将会满足条件,那么check(num2[num[a[i]]] + 1) * num[a[i]] == i - 1的情况。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int num[maxn];
int a[maxn];
int num2[maxn]; 
int vis[maxn];
int main(){
    Sca(N);
    int ans = 1;
    int cnt = 0;
    int MAX2 = 0,MAX = 0;
    for(int i = 1; i <= N ; i ++){
        Sca(a[i]);
        if(!vis[a[i]]){
            vis[a[i]] = 1;
            cnt++;
        }
        if(i == 6){
        //    puts("bug");
        }
        if(num2[num[a[i - 1]]] * num[a[i - 1]] == i - 1){
            ans = i;
        }
        num2[num[a[i]]]--;
        num[a[i]]++;
        num2[num[a[i]]]++;
        if(num2[num[a[i]]] * num[a[i]] == i - 1){
            ans = i;
        }
        if(num2[num[a[i]] + 1]){
            if((num2[num[a[i]]] + 1) * num[a[i]] == i - 1) ans = i;
        }
    }
    Pri(ans);
    return 0;
}
B

 

C1 C2.

思路并不难想,找出所有斜率相同的线,假设有k条斜率相同的线,这k条线对最终产生的贡献将会是k * (所有直线数目 - k )

有问题在于各个直线容易出现重合的情况,需要判重,意识到输出的都是整数,可以用y1 - y2 / x1 - x2的方法求出每条直线的一般式ax + by + c = 0中的a,b,c,除去他们的gcd化为最简情况,直接上map<pair<pair<LL,LL>,LL>,int>比较

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 1010;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
map<pair<PLL,LL>,int>Q;
map<PLL,int>P;
struct Point{
    LL x,y;
}point[maxn];
int main(){
    Sca(N);
    for(int i = 1; i <= N ; i ++) scanf("%lld%lld",&point[i].x,&point[i].y);
    int cnt = 0;
    for(int i = 1; i <= N ; i ++){
        for(int j = i + 1; j <= N ; j ++){
            LL ka = point[i].y - point[j].y,kb = point[i].x - point[j].x,kc = point[i].y * point[j].x - point[i].x * point[j].y;
            LL p = __gcd(ka,kb);
            ka /= p; kb /= p; kc /= p;
            if(ka < 0 || (!ka && kb < 0)){
                 ka = -ka; kb = -kb;
            }
            if(!Q[mp(mp(ka,kb),kc)]){
                Q[mp(mp(ka,kb),kc)] = 1;
                P[mp(ka,kb)]++;
                cnt++;
            } 
        }
    }
    LL ans = 0;
    map<PLL,int>::iterator it;
    for(it = P.begin(); it != P.end(); it++){
        pair<PLL,int> p = *it;
        ans += (cnt - p.second) * p.second;
    }
    Prl(ans / 2);
    return 0;
}
C

 

posted @ 2019-05-16 21:58  Hugh_Locke  阅读(470)  评论(0编辑  收藏  举报