【组队训练】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;
}
View Code

然后看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;
}
View Code

这是队友坑在了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;
}
View Code

然后队友去看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;
}
View Code

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;
}
View Code

然后队友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;
}
View Code

 

这时我比较累了,不想看题,ys看完G题,我们仨讨论下,没什么结果,这时候时间也差不多了,剩几分钟。。。于是就撤了。。

 

感觉比亚洲区域赛简单(当然,难题还是很难的。。。。)

还是继续加油啊 太慢了 后面都没时间了。。。

 

转载于:https://www.cnblogs.com/wenruo/p/5857768.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值