【组队训练】2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest
好多oj都崩掉了,于是打了cf。。
开始开的最后一题。。。尼玛题好长终于看完了。。。神题不会。。。。
I过了好多人。。看了下,一眼题。。。随便敲了下,1A
int a[105]; int main(){ int n, k; cin >> n >> k; int tmp; for (int i = 1; i <= n; ++i) { cin >> tmp; a[tmp]++; } int ans = 0; for (int i = 1; i <=k; ++i) { if (a[i] > n/k) ans += a[i] - n/k; } cout << ans; return 0; }
然后看J题。搜索,还是水题。1A
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> typedef long long ll; using namespace std; const int maxn = 15; int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1}; int n, m; int mp[maxn][maxn][4]; int vis[maxn][maxn]; char a[maxn][maxn]; int ans; int dx(char ch) { if (ch == 'U') return 0; if (ch == 'R') return 1; if (ch == 'D') return 2; if (ch == 'L') return 3; return -1; } bool check(int x, int y) { if (x < n && x >= 0 && y < m && y >= 0 && a[x][y] != '*') return true; return false; } void dfs(int x, int y, int d) { if (mp[x][y][d]) return ;mp[x][y][d] = 1; if (!vis[x][y]) { //printf(">>%d %d\n", x, y); vis[x][y] = 1; ans++; } //printf(">>%d %d %d\n", x, y, d); for (int i = 0; i < 4; ++i) { int nx = x + dir[(d+i)%4][0]; int ny = y + dir[(d+i)%4][1]; //printf(">>>%d %d %d\n", nx, ny, (d+i)%4); //if (mp[nx][ny][(d+i)%4]) return ; if (check(nx, ny)) { dfs(nx, ny, (d+i)%4); break; } } } int main(){ cin >> n >> m; for (int i = 0; i < n; ++i) { scanf("%s", a[i]); } int d; int x, y; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (dx(a[i][j]) >= 0) { vis[i][j] = 1; d = dx(a[i][j]); x = i, y = j; break; } } } //printf(">>%d %d %d\n", x, y, d); ans = 1; for (int i = 0; i < 4; ++i) { int nx = x + dir[(d+i)%4][0]; int ny = y + dir[(d+i)%4][1]; if (check(nx, ny)) { dfs(nx, ny, (d+i)%4); break; } } printf("%d\n", ans); return 0; }
这是队友坑在了A题,wa了好久。。。我帮着看了一眼。。。。写的实在是太糟糕了。。。
我去搞F,数组开小了RE了几次。优先队列+二分做的。
#include <bits/stdc++.h> typedef long long ll; using namespace std; const int N = 105; struct node { int s, t; int last; int id; bool operator < (const node rhs) const { if (t == rhs.t) return last < rhs.last; return t > rhs.t; } } a[N]; vector<int> f[100005]; int main(){ int n; scanf("%d", &n); int l = 1, r = 100000; int ti = 0; for (int i = 0; i < n; ++i) { scanf("%d%d", &a[i].s, &a[i].t); r = min(r, a[i].t-a[i].s); ti = max(ti, a[i].t); f[a[i].s].push_back(i); a[i].id = i; } //printf(">>%d %d\n", r, ti); int ans = 0; while (l <= r) { int mid = (l+r)>>1; //printf("%d %d %d\n", l, r, mid); priority_queue<node> que; for (int i = 0; i < n; ++i) a[i].last = mid; bool fg = false; for (int i = 0; i < ti; ++i) { //printf("t=%d\n", i); if (f[i].size()) { for (int j = 0; j < f[i].size(); ++j) { que.push(a[f[i][j]]); } } if (que.size()) { node tmp = que.top();//printf("tmp=%d\n", tmp.s); if (tmp.t <= i) { fg = true; break; } if (--a[tmp.id].last == 0) que.pop(); } } if (que.size() || fg) { r = mid-1; } else{ l = mid+1; ans = mid; } } printf("%d\n", ans*n); return 0; }
然后队友去看D,我看A。。。由于是在看不懂队友的代码。。删掉重写的。。。
D貌似挺好写的,一会就A了。。
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <iostream> #include <map> #include <queue> #include <stack> #include <cmath> //#pragma comment(linker, "/STACK:102400000,102400000") using namespace std; #define PF(x) cout << "debug: " << x << " "; #define EL cout << endl; #define PC(x) puts(x); typedef long long ll; #define CLR(x, v) sizeof (x, v, sizeof(x)) using namespace std; const int INF = 0x5f5f5f5f; const int N= 2e5 + 10; const int mod=1e9 + 7; const int maxn = 1010; const double eps = 1e-8; const double PI = acos(-1.0); int t; int sgn(double x){ if(fabs(x) < eps) return 0; if(x < 0) return -1; else return 1; } struct Point{ double x,y; Point() { } Point(double _x,double _y){ x = _x,y = _y; } Point operator - (const Point &b) const{ //相对坐标 return Point(x - b.x,y - b.y); } double operator ^(const Point &b)const{//叉积 return x*b.y - y*b.x; } double operator *(const Point &b)const{//点积 return x*b.x + y*b.y; } void transXY(double B){ double tx = x,ty = y; x = tx*cos(B) - ty*sin(B); y = tx*sin(B) + ty*cos(B); } }; struct Line{ Point s,e; Line() { } Line (Point _s,Point _e){ s = _s,e = _e; } //两直线相交求交点 //第一个值为0表示直线重合,为1表示平行,为2是相交 //只有第一个值为2时交点才有意义 pair<int,Point> operator &(const Line &b) const{ Point res = s; if(sgn((s-e)^(b.s-b.e)) == 0){ if(sgn((s-b.e)^(b.s-b.e)) == 0) return make_pair(0,res);//重合 else return make_pair(1,res); } double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e)); res.x += (e.x-s.x)*t; res.y += (e.y-s.y)*t; return make_pair(2,res); } }; double dist(Point a,Point b){ return sqrt((b-a)*(b-a)); } bool Seg_inter_line(Line l1,Line l2){//判断直线l1与线段l2是否相交 return sgn((l2.s - l1.e) ^ (l1.s-l1.e)) * sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0; } bool inter(Line l1,Line l2){ return max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) && max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) && max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) && max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) && sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0&& sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0; } int n,ans[maxn]; Line line[maxn]; int main(){ // freopen("in.txt","r",stdin); cin>>n; double ts,s,f,tf; for(int i = 1;i <= n;i++){ scanf("%lf%lf%lf",&ts,&s,&f); double max1,min1; if(f <= s) max1 = s,min1 =f; else max1 = f,min1 = s; tf = (max1 - min1) + ts; line[i] = Line(Point(ts,s),Point(tf,f)); } for(int i = 1;i <= n;i++) for(int j = i+1;j <= n;j++){ if(inter(line[i],line[j])) ans[i]++,ans[j]++; } for(int i = 1;i <= n;i++){ printf("%d",ans[i]); if(i == n) printf("\n"); else printf(" "); } return 0; }
A题犯了几个sb错误,还好,改好之后就过了。。
#include <bits/stdc++.h> using namespace std; const int N = 20005; string a[N]; string login[N], domain[N]; bool bmail[N]; map<string, int> mp; vector<int> ans[N]; int main() { int n; //freopen("in.txt","r",stdin); cin >> n; for (int i = 0; i < n; ++i) { cin >> a[i]; int p = a[i].find('@'); login[i] = a[i].substr(0, p); domain[i] = a[i].substr(p+1, a[i].length()-p-1); transform(domain[i].begin(), domain[i].end(), domain[i].begin(), ::tolower); if (domain[i] == "bmail.com") bmail[i] = 1; } for (int i = 0; i < n; ++i) { if (bmail[i]) { int p = login[i].find('+'); login[i] = login[i].substr(0, p); for (string::iterator it = login[i].begin(); it != login[i].end(); ++it) { if ( *it == '.') { login[i].erase(it); --it; } } } transform(login[i].begin(), login[i].end(), login[i].begin(), ::toupper); //cout << login[i] << " " << domain[i] << endl; } int cnt = 1; for (int i = 0; i < n; ++i) { string tmp = login[i]+domain[i]; //cout << tmp << endl; if (mp[tmp] == 0) mp[tmp] = cnt++; ans[mp[tmp]].push_back(i); } cout << cnt-1 << endl; for (int i = 1; i < cnt; ++i) { cout << ans[i].size(); for (int j = 0; j < ans[i].size(); ++j) { cout << " " << a[ ans[i][j] ]; } cout << endl; } return 0; }
然后队友B有了思路。。写了下,也过了。。。
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> #include <iostream> #include <map> #include <queue> #include <stack> #include <cmath> //#pragma comment(linker, "/STACK:102400000,102400000") using namespace std; #define PF(x) cout << "debug: " << x << " "; #define EL cout << endl; #define PC(x) puts(x); typedef long long ll; #define CLR(x, v) sizeof (x, v, sizeof(x)) using namespace std; const int INF = 0x5f5f5f5f; const int maxn = 4010; const int mod = 1e9 + 7; const double eps = acos(-1); const double PI= atan(1.0)*4; int n,bx[maxn],tree[maxn],sum[maxn]; struct st{ int a,b; }re[maxn]; map<int,int>q; bool cmp(st x,st y){ return x.a<y.a; } void Add(int k , int num) { while(k <= n) { tree[k] += num; k += k&(-k); } } int Sum(int k) { int sum = 0; while(k > 0) { sum += tree[k]; k -= k&(-k); } return sum; } int main(){ // freopen("in.txt","r",stdin); cin>>n; int t1,t2; for(int i = 1;i <= n;i++){ scanf("%d%d",&t1,&t2); if(t1 > t2) swap(t1,t2); re[i].a = t1; re[i].b = t2; //cout<<re[i].a<<" "<<re[i].b<<endl; bx[i] = re[i].b; } sort(re+1,re+1+n,cmp); sort(bx+1,bx+1+n); int num = bx[1],cnt = 1; q[bx[1]] = 1,sum[1]++; for(int i = 2;i <= n;i++){ if(bx[i] != num){ Add(cnt,sum[cnt]); cnt++; q[bx[i]] = cnt; num = bx[i]; sum[cnt]++; // cout<<cnt<<" "<<bx[i]<<endl; } else sum[cnt]++; } Add(cnt,sum[cnt]); ll s = 0,x,y; //for(int i = 1;i <= cnt;i++) // cout<<i<<" "<<Sum(i)<<endl; for(int i = 1;i <= n;i++){ //cout<<Sum(i)<<endl; for(int j = i;j <= n;j++){ int k = Sum(cnt)-Sum(q[re[j].b]-1); ll sx = (ll)k*re[i].a*re[j].b; // cout<<re[i].a<<" "<<re[j].b<<endl; if(s < sx){ s = sx; x = re[i].a; y = re[j].b; } // cout<<s<<endl; //cout<<x<<" "<<y<<endl; } Add(q[re[i].b],-1); } printf("%lld\n",s); cout<<x<<" "<<y<<endl; //printf("%d %d\n",x,y); return 0; }
这时我比较累了,不想看题,ys看完G题,我们仨讨论下,没什么结果,这时候时间也差不多了,剩几分钟。。。于是就撤了。。
感觉比亚洲区域赛简单(当然,难题还是很难的。。。。)
还是继续加油啊 太慢了 后面都没时间了。。。