SCUT第四次訓練賽(歸併排序 sort 搜索 搜索2 並查集 高精度乘法 二分 Dating with girls(1) 均分紙牌 導彈攔截 A + B Problem II)

SCUT第四次訓練賽(歸併排序 sort 搜索 搜索2 並查集 高精度乘法 二分 Dating with girls(1) 均分紙牌 導彈攔截 A + B Problem II)

https://acm.scut.space/vJudge/contest/id/12
歸併排序:求逆序對

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int M = 1000000;
typedef long long LL;

LL res = 0;
int a[M], bri[M];

void sort(int l, int r) {
    //cout<<l<<" "<<r<<endl;
    if (l + 1 >= r) return;
    int mid = (l + r) >> 1;
    sort(l, mid);
    sort(mid, r);
    int p = l, q = mid, cnt = 0;
    while (p != mid || q != r) {
        //cout<<p<<" "<<q<<endl;
      if (p == mid || (q < r && a[p] > a[q])) {
        bri[++cnt] = a[q++];
        if (p < mid) res += mid - p;
      }
      else 
        bri[++cnt] = a[p++];
    }
    for (int i = l; i < r; ++i) {
      a[i] = bri[i-l+1];
    }
}

int main()
{
    freopen("in.txt", "r", stdin);
    int n;
    while(cin>>n && n) {
      res = 0;
      for (int i = 1; i <= n; ++i) cin>>a[i];
      sort(1, n+1);
      //for (int i = 1; i <= n; ++i) cout<<a[i]<<" ";
      //cout<<endl;
      cout<<res<<endl;
    }
    return 0;
}

sort:桶排序+讀入輸出優化

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int M = 1000000 + 10;

int get() {
    int X = 0, w = 1;
    char ch=0;
    while(ch<'0' || ch>'9') { if(ch == '-') w = -1; ch = getchar(); }
    while(ch>='0' && ch<='9') X=X * 10+ch-'0',ch = getchar();
    return X*w;
}

void put(int x) {
    if (x < 0) putchar('-'), x = -x;
    if (x < 10) {
      putchar(x + '0');
      return;
    }
    put(x / 10);
    putchar(x % 10 + '0');
}

int a[M], b[1000000 + 10];

int main()
{
    freopen("in.txt", "r", stdin);
    int n, m;
    while (~scanf("%d%d", &n, &m)) {
      memset(b, 0, sizeof(b));
      for (int i = 1; i <= n; i++) a[i] = get(), b[a[i]+500000]++;
      if (m >= n) {
        for (int i = 1000000; i >= 0; --i) {
          if (b[i]) {
            put(i - 500000);if (m > 1) printf(" ");--m;
          }
        }
        printf("\n");
        continue;
      } 
      for (int i = 1000000; i >= 0 && m > 0; --i) {
        if (b[i]) {
          put(i - 500000);if (m > 1) printf(" ");--m;
        }
      }
      printf("\n");
    }
    return 0;
}

搜索:dfs

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

int used[6], bri[6], a[6], ans[1000], tot = 0, have[10000];

void dfs(int tep){
    if (tep == 5) {
      int res = 0;
      for (int i = 1; i <= 4; ++i)
        res = res * 10 + bri[i];
      if (res >= 1000 && !have[res]) ans[++tot] = res, have[res] = 1;
      return;
    }
    for (int i = 1; i <= 4; ++i)
      if (!used[i]){
        bri[tep] = a[i];
        used[i] = 1;
        dfs(tep + 1);
        used[i] = 0;
      } 
}

int main()
{
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    scanf("%d%d%d%d", &a[1], &a[2], &a[3], &a[4]);
    while (1) {
      if (!a[1] && !a[2] && !a[3] && !a[4]) break;
      memset(have, 0, sizeof(have));
      memset(used, 0, sizeof(used));
      memset(ans, 0, sizeof(ans));
      tot = 0;
      dfs(1);
      sort(ans+1, ans+1+tot);
      ans[0] = -1;
      for (int i = 1; i <= tot; ++i) {
        if (ans[i]/1000 != ans[i-1]/1000 && i != 1) printf("\n");
        printf("%d", ans[i]);
        if (ans[i]/1000 == ans[i+1]/1000) printf(" ");
      }
      scanf("%d%d%d%d", &a[1], &a[2], &a[3], &a[4]);
      printf("\n");
      if (a[1] || a[2] || a[3] || a[4]) printf("\n");
      else break;
    }
    return 0;
}

搜索2:dfs

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int M = 30;
#define check (tx<1||tx>h||ty<1||ty>w||map[tx][ty]=='#'||vis[tx][ty])

char map[M][M];
bool vis[M][M];
int d1[6] = {1, -1, 0, 0};
int d2[6] = {0, 0, 1, -1};
int ans = 0, w, h;

void dfs(int x, int y) {
    vis[x][y] = 1, ans++;
    for (int i = 0; i < 4; ++i) {
      int tx = x + d1[i];
      int ty = y + d2[i];
      if (check) continue;
      dfs(tx, ty);
    }
}

int main()
{
    freopen("in.txt", "r", stdin);
    while (scanf("%d%d", &w, &h) && w) {
      memset(vis, 0, sizeof(vis));
      for (int i = 1; i <= h; ++i)
        scanf("%s", &map[i][1]);
      ans = 0;
      for (int i = 1; i <= h; ++i)
        for (int j = 1; j <= w; ++j)
          if (map[i][j] == '@') {
            dfs(i, j);
            break;
          }
      printf("%d\n", ans);
    }
    return 0;
}

並查集:同名

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
using namespace std;
const int M = 1000000;

int read() {
    int k = 1, x = 0; char ch = getchar();
    while (ch<'0' || ch>'9') {
      if (ch == '-') k = -1;
      ch = getchar();
    }
    while ('0'<=ch && ch<='9') {
      x = x * 10 + ch - '0';
      ch = getchar();
    }
    return k * x;
}

int f[M];
set<int> st;

int find(int x) {
    if (f[x] == x) return x;
    return f[x] = find(f[x]);
}

int main()
{
    freopen("in.txt", "r", stdin);
    int n, m, cases = 0;
    while (scanf("%d%d", &n, &m) && n) {
      for (int i = 1; i <= n; ++i) f[i] = i;
      for (int i = 1; i <= m; ++i) {
        int a = read(), b = read();
        int l = find(a), r = find(b);
        if (l != r) f[l] = r;
      }
      st.clear();
      for (int i = 1; i <= n; ++i) 
        st.insert(find(i));
      printf("Case %d: %d\n", ++cases, st.size());
    }
    return 0;
} 

Regroup:並查集

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int M = 200000;
const int INF = 0x7fffffff;

int read() {
    int k = 1, x = 0;
    char ch = getchar();
    while (ch<'0'||ch>'9') {
      if (ch == '-') k = -1;
      ch = getchar();
    }
    while ('0'<=ch&&ch<='9') {
      x = x * 10 + ch - '0';
      ch = getchar();
    }
    return k * x;
}

int n, m, k;
int size[M], value[M], f[M];

int find(int x) {
    if (f[x] == x) return x;
    return f[x] = find(f[x]); 
}

int main()
{
    freopen("in.txt", "r", stdin);  
    while (~scanf("%d%d%d", &n, &k, &m)) {
      memset(size, 0, sizeof(size));
      for (int i = 0; i < n; ++i)
        value[i] = INF, f[i] = i; 
      for (int i = 1; i <= k; ++i) {
        int r = read(), c = read();
        ++size[c];
        value[c] = min(value[c], r);
      }
      for (int i = 1; i <= m; ++i) {
        char qus[5]; int x, y;
        scanf("%s", qus);
        if (qus[0] == 'A') {
          x = read(), y = read();
          if (find(y) != y) printf("Reject\n");
          else {
            printf("Accept\n");
            value[y] = min(value[y], x);
            size[y]++;
          }
        }
        else if (qus[0] == 'M') {
          x = read(), y = read();
          if (x == y) {printf("Reject\n");continue;}//*******
          if (find(y) != y || find(x) != x) printf("Reject\n");
          else {
            printf("Accept\n");
            f[y] = x;
            value[x] = min(value[x], value[y]);
            size[x] += size[y];
          }
        } 
        else if (qus[0] == 'G'){
          x = read();
          if (find(x) != x) {
            printf("Company %d is a part of company %d.\n", x, find(x));
            continue;
          }
          if (size[x] == 0) {
            printf("Company %d is empty.\n", x);
            continue;
          }
          printf("Lowest rate: %d.\n", value[x]);
        }
      }
      printf("\n"); 
    }
    return 0;
}

高精度乘法:同名

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int M = 2500;

char a[M], b[M];
int num1[M], num2[M], num[M];

int main()
{
    freopen("in.txt", "r", stdin);
    while(~scanf("%s%s", a, b)) {
        memset(num, 0, sizeof(num));
        int len3 = 1;
        int len1 = strlen(a);
        int len2 = strlen(b);
        for (int i = 1; i <= len1; ++i)
          num1[i] = a[len1-i] - '0';
        for (int i = 1; i <= len2; ++i)
          num2[i] = b[len2-i] - '0';
        for (int i = 1; i <= len1; ++i)
          for (int j = 1; j <= len2; ++j)
            num[i+j-1] += num1[i] * num2[j];
        for (int i = 1; i <= len1 + len2 + 1; ++i) {
          num[i+1] += num[i] / 10;
          num[i] %= 10;
        }
        for (int i = len1+len2+1; i >= 1; i--) {
          if (num[i]) {
            len3 = i;
            break;
          }
        }
        for (int i = len3; i >= 1; i--)
          cout<<num[i];
        cout<<endl;
    }
    return 0;
}

二分:同名

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const double pie = 3.141592653589;
const int M = 100000 + 10;

int n, f;
double v[M];

bool check(double x) {
    int res = 0;
    for (int i = 1; i <= n; ++i)
      res += (int)(v[i] / x);
    return res >= f;
}

int main()
{
    freopen("in.txt", "r", stdin);
    int T;
    double r_;
    cin>>T;
    while (T--) {
      cin>>n>>f;
      f++;
      double l = 0, r = 0, ans;
      for (int i = 1; i <= n; ++i) {
        cin>>r_;
        v[i] = r_ * r_; 
        r = max(r, v[i]);
      }
      while (r - l > 1e-4) {
        double mid = (l + r) / 2;
        if (check(mid)) l = mid, ans = mid;
        else r = mid;
      }
      printf("%.4f\n", ans * pie);
    }
    return 0;
}

Dating with girls(1):我用的Treap,還可以二分,stl的set等

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF = 0x7fffffff;
const int M = 100000 + 10;

int read(){
    int k = 1, x = 0; char ch = getchar();
    while (ch<'0'||ch>'9') { if(ch=='-') k=-1; ch = getchar(); }
    while ('0'<=ch&&ch<='9') { x=x*10+ch-'0'; ch = getchar(); }
    return k*x;
}

int n, k;

struct Treap{
    int root, treapCnt, key[M], priority[M],
    childs[M][2], size[M], cnt[M];

    void init() {
        root = 0;
        treapCnt = 0;
        size[0] = 0;
        priority[0] = INF;
    }

    void update(int x) {
        size[x] = size[childs[x][0]] + cnt[x] + size[childs[x][1]];
    }

    void rotate(int &x, int t) {
        int y = childs[x][t];
        childs[x][t] = childs[y][1-t];
        childs[y][1-t] = x;
        update(x);
        update(y);
        x = y;
    }

    void _insert(int &x, int k) {
        if (x) {
          if (key[x] == k) return;
          else {
            int t = key[x] < k;
            _insert(childs[x][t], k);
            if (priority[childs[x][1]] < priority[childs[x][0]])
              rotate(x, t);
          }
        }
        else {
          x = ++treapCnt;
          key[x] = k;
          cnt[x] = 1;
          priority[x] = rand(); 
          childs[x][0] = childs[x][1] = 0;
        }
        update(x);
    }

    bool _search(int& x, int k) {
        if (!x) return 0;
        if (key[x] == k) return 1;
        if (key[x] > k) return _search(childs[x][0], k);
        else return _search(childs[x][1], k);
    }

    int _getKth(int &x, int k) {
        if (k <= size[childs[x][0]]) return _getKth(childs[x][0], k);
        k -= size[childs[x][0]] + cnt[x];
        if (k <= 0) return key[x];
        return _getKth(childs[x][1], k);
    }

    void insert(int x) {
        _insert(root, x);
    }

    int getKth(int x) {
        return _getKth(root, x);
    }

    bool search(int k) {
        return _search(root, k);
    }
}set;

int ans = 0;

void dfs(int x){
    if (!x) return;
    if (set.search(k-set.key[x])) ans++;
    dfs(set.childs[x][0]);
    dfs(set.childs[x][1]);
}

int main()
{
    freopen("in.txt", "r", stdin);
    int T, num;
    T = read();
    while (T--) {
      set.init();
      n = read(), k = read();
      for (int i = 1; i <= n; ++i) {
        num = read();
        set.insert(num);
      }
      ans = 0;
      dfs(set.root);
      printf("%d\n", ans);
    }
    return 0;
}

均分紙牌:貪心

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int M = 200;

int a[M], b[M];

int main()
{
    int n, sum = 0;
    cin>>n;
    for (int i = 1; i <= n; ++i) {
      cin>>a[i];
      sum += a[i];
      b[i] = a[i];
    }
    int tot = sum / n, ans1 = 0, ans2 = 0;
    for (int i = 1; i < n; ++i) {
      if (a[i] != tot) {
        a[i + 1] += a[i] - tot;
        ans1++; 
      }
    }
    for (int i = n; i > 1; i--) {
      if (b[i] != tot) {
        b[i - 1] += b[i] - tot;
        ans2++;
      }
    }
    cout<<min(ans1, ans2);
    return 0;
}

導彈攔截:狀態維護

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x7fffffff;

int read(){
    int k = 1, x = 0; char ch = getchar();
    while (ch<'0' || ch>'9') {
      if (ch == '-') k = -1;
      ch = getchar();
    }
    while ('0'<=ch && ch<='9') {
      x = x * 10 + ch - '0';
      ch = getchar();
    }
    return x * k;
}

const int M = 100000 + 10;

struct Point{
    int x, y, dis1, dis2;
    bool operator < (const Point& a) const{
        return dis1 < a.dis1;
    }
}p1, p2, p[M];

int dis(Point a, Point b){
    return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}

int main()
{
    freopen("in.txt", "r", stdin);
    p1.x = read(), p1.y = read();
    p2.x = read(), p2.y = read();
    int n = read();
    for (int i = 1; i <= n; ++i) {
      p[i].x = read(), p[i].y = read();
      p[i].dis1 = dis(p1, p[i]);
      p[i].dis2 = dis(p2, p[i]);
    }
    sort(p+1, p+1+n);
    int ans = p[n].dis1, re = 0;
    for (int i = n - 1; i >= 1; i--) {
      re = max(re, p[i+1].dis2);
      ans = min(ans, re + p[i].dis1); 
    }
    re = max(re, p[1].dis2);
    ans = min(ans, re);
    printf("%d", ans);
    return 0;
}

A + B Problem II:呵呵

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int M = 1020;

int a[M], b[M], ans[M];
char c[M], d[M];

int main()
{
    freopen("in.txt", "r", stdin);
    int T, cases = 0;
    cin>>T;
    while(T--) {
      memset(ans, 0, sizeof(ans));
      memset(a, 0, sizeof(a));
      memset(b, 0, sizeof(b));
      cin>>c>>d;
      int len1 = strlen(c);
      int len2 = strlen(d);
      for (int i = 1; i <= len1; ++i)
        a[i] = c[len1-i] - '0';
      for (int i = 1; i <= len2; ++i)
        b[i] = d[len2-i] - '0';
      for (int i = 1; i <= max(len1, len2); i++)
        ans[i] = a[i] + b[i];
      for (int i = 1; i <= 1005; i++){
        ans[i+1] += ans[i] / 10;
        ans[i] %= 10;
      }
      printf("Case %d:\n%s + %s = ", ++cases, c, d);
      int len = 1;
      for (int i = 1005; i >= 1; i--)
        if (ans[i]) {
          len = i;
          break;
        }
      for (int i = len; i >= 1; i--)
        cout<<ans[i];
      cout<<endl;
      if (T != 0) cout<<endl;
    }
    return 0;
}
發佈了32 篇原創文章 · 獲贊 1 · 訪問量 3981
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章