算得上第一次好好写Codeforce吧,总体感受,题目很灵活,我英语很菜,读题1小时,写题半小时;
总结:对于想B题这种的题目,如何判断条件,f数组不难想,rf数组还是要想一下的;
对于C,计算几何知识基本空白...需要补一下;
题目链接:https://codeforces.com/contest/1163
A:
签到,直接推个公式就行,注意0的时候要特判一下。
#include <cstdio> #include <iostream> #include <cstring> using namespace std; int main() { //freopen("in.txt", "r", stdin); int n, a; //while(cin>>n>>a) cin>>n>>a; { if(a==0) cout<<"1"<<endl; else if(a<=(n/2)) cout<<a<<endl; else cout<<n-a<<endl; } return 0; }
B(1,2):
题意:给出n天对应的颜色,求一个长度为x的前缀满足从前面x天中能够去除一天使得剩余的x-1的天中,每种颜色的天数相同(英语太菜了...应该大概就这意思吧)
数据范围天数<10^5, 颜色的种类数<=10^5;
题解:满足条件的前x天可以划分成4种情况:
1.只有一种颜色
2.每种颜色只有1天
3.其中一种颜色有一天,其他种类的颜色相等
4.其中一种颜色比其他的颜色多一(其他的颜色数目相等)
想要对这四种情况做出判定只要维护: f [i] 第i种颜色出现的次数, rf[i] 出现 i 次的颜色 的种类, max_num 前i天的的最大f[k] (k<=i) 就是某种颜色出现最多的次数;
#include <bits/stdc++.h> using namespace std; const int maxn=1e5+5; int col, f[maxn], rf[maxn]; /// f是某种颜色出现的次数; rf是某种颜色出现i次的颜色种类数目; int main() { int n; cin>>n; int col, num_max=0, ans=0; ///num_max维护的是某种颜色出现的最大次数 for(int i=1; i<=n; i++) { cin>>col; rf[f[col]]--; rf[++f[col]]++; num_max=max(num_max, f[col]); if(rf[i]==1) ans=i; ///只有一种颜色(出现了i次) else if(rf[1]==i) ans=i; ///每种颜色只出现一次 else if(rf[1]==1 && rf[num_max]*num_max==i-1) ans=i; ///有一种出现了1次,其他的出现了相同的次数 else if(rf[num_max-1]*(num_max-1)==i-num_max && rf[num_max]==1) ans=i; ///有一种多出现了一次,其他的出现相同次数 } printf("%d ", ans); return 0; }
C(1,2):
题意:给出n个点的坐标,求这n个所形成的直线(同一条只算一条)中有多少组(2个一组)是相交的
题解:就是用一个map<pair<int, int>, set<long long>> slope_map 维护即可
分别是直线ax+by=c,中的a,b,c;
不平行的就是相交,注意要去除重复的直线;
总结:注意数据范围 截距一定要用long long 存;
对于经过(x1, y1), (x2, y2) 的直线 ax+by=c来说
a=y1-y2, b=x1-x2 ;
#include <bits/stdc++.h> using namespace std; const int MAXN=1010; int x[MAXN], y[MAXN]; map<pair<int,int>, set<long long>> slope_map; int gcd(int a, int b){ if(a==0) return b; return gcd(b%a, a); } int main() { int n; cin>>n; for(int i=1; i<=n; i++) cin>>x[i]>>y[i]; long long ans=0, all_line=0; for(int i=1; i<n; i++) for(int j=i+1; j<=n; j++) { int x1 = x[i], y1 = y[i], x2 = x[j], y2 = y[j]; int a=y1-y2, b=x1-x2; int g=gcd(a, b); a/=g; b/=g; if(a<0 || (a==0 && b<0)) a=-a, b=-b; pair<int, int> slope(a,b); long long c=(long long)a*x[i]-(long long)b*y[i]; if(!slope_map[slope].count(c)) { ans+=all_line-slope_map[slope].size(); all_line++; slope_map[slope].insert(c); } } printf("%I64d ", ans); return 0; }