您的位置:首页 > 其它

SCUT第四次训练赛(归并排序 sort 搜索 搜索2 并查集 高精度乘法 二分 Dating with girls(1) 均分纸牌 导弹拦截 A + B Problem II)

2017-10-08 09:01 459 查看

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
4000
;

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
.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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SCUT