Codeforces #308(div2)

A. Vanya and Table

题意: 每次给区域内每个格子加1 问最后总和

思路: 如果一个一个的算的话  - - x和y是倒着读的~ 要注意一下~ 算的话就无所谓了

参考code:

//
//  Created by TaoSama on 2015-06-19
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

int n, a[105][105];

int main() {
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
	ios_base::sync_with_stdio(0);

    while(cin >> n){
		memset(a, 0, sizeof a);
		int maxx = -INF, maxy = -INF;
		for(int i = 1; i <= n; ++i){
			int x1, y1, x2, y2; cin >> y1 >> x1 >> y2 >> x2;
			maxx = max(max(maxx, x1), x2);
			maxy = max(max(maxy, y1), y2);
			for(int dx = x1; dx <= x2; ++dx)
				for(int dy = y1; dy <= y2; ++dy)
					a[dx][dy]++;
		}
		int ret = 0;
		for(int i = 1; i <= maxx; ++i)
			for(int j = 1; j <= maxy; ++j)
				ret += a[i][j];
		cout << ret << '\n';
    }
	return 0;
}

B. Vanya and Books

题意: 求1-n所有数字的位数个数之和

思路: 先打个表~ 每个位数个数最大的值~ 然后算算就好了~ 顺带一提 log10(n) + 1就是位数

参考code:

//
//  Created by TaoSama on 2015-06-19
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

long long n, a[10];

long long ten(int x){
	long long ret = 1;
	for(int i = 1; i <= x; ++i)
		ret *= 10;
	return ret;
}

int main() {
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
	ios_base::sync_with_stdio(0);

	while(cin >> n){
		long long x = 9;
		for(int i = 1; i <= 9; ++i){
			a[i] = a[i - 1] + x * i;
			x *= 10;
//			cout << a[i] << endl;
		}
		int d = log10(n) + 1;
//		cout << d << endl;
		long long ans = a[d - 1] + (n - ten(d - 1) + 1) * d;
		cout << ans << endl;
	}
	return 0;
}


C. Vanya and Scales

题意: 有101个砝码每个砝码是w^0, w^1, w^2, .... , w^100 然后给一个物品m 问两边都放一些砝码可不可以使得天平平衡~ 一个砝码只能用一次

思路: 赛场的时候没注意到一个只能拿一次 - - 思路一直不对~ 然后经过zw提醒 以及讲解才明白 0 0

m一定能表示成 m = a1*w^0 + a2*w^1 + ... + an*w^n  (a1...an为-1,0,1)

然后每次不断的提公因式+1-1就好了 能搞到0说明可以 重复用了砝码就不行

还有一个思路~ 我们可以证明2和3进制一定可以~2进制参考计算机存储和多重背包二进制优化~ 3进制那么就-1,0,1~ 也是一定可以的~ 具体的可以查wiki

然后更大的直接暴力 三种情况 放左边 放右边 和不放 跟上一个思路挺相近~

参考code:

//
//  Created by TaoSama on 2015-06-19
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

long long w, m, ct;
bool vis[105];

void dfs(int m, int k) {
    if(m == 0) throw 1;
    while(m % w == 0) {
        m /= w;
        k ++;
        if(k > 100) return;
    }
    if(vis[k]) return;
    vis[k] = 1;
    dfs(m + 1, k);
    dfs(m - 1, k);
    vis[k] = 0;
}

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(cin >> w >> m) {
        memset(vis, false, sizeof vis);
        try {
            dfs(m, 0);
        } catch(int) {
            cout << "YES\n";
            continue;
        }
        cout << "NO\n";
    }
    return 0;
}


D. Vanya and Triangles

题意: 平面2000个点 问能组成最多的非0面积的三角形个数 - -

思路: 时限太松 - - 或者CF评测姬跑的太快~ 然后n^3/6数量级的也过了~ - -

正解应该是 用总可能数减去共线那些 这样枚举两个点组成的向量就可以了

参考code:

n^3 brute force

//
//  Created by TaoSama on 2015-06-19
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

int n, x[2005], y[2005];

int xmul(int i, int j, int k){
	return (x[i] - x[k]) * (y[j] - y[k]) - (x[j] - x[k]) * (y[i] - y[k]);
}

int main() {
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
	ios_base::sync_with_stdio(0);

	while(scanf("%d", &n) == 1){
		for(int i = 1; i <= n; ++i) scanf("%d%d", x + i, y + i);
		if(n < 3) {
			puts("0");
			continue;
		}
		long long ans = 0;
		for(int i = 1; i <= n; ++i){
			for(int j = i + 1; j <= n; ++j){
				for(int k = j + 1; k <= n; ++k){
					if(xmul(i, j, k)) ans ++;
				}
			}
		}
		printf("%I64d\n", ans);
	}
	return 0;
}



n^2

//
//  Created by TaoSama on 2015-06-19
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

int n, x[2005], y[2005], a[405][405];

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(scanf("%d", &n) == 1) {
        for(int i = 1; i <= n; ++i) scanf("%d%d", x + i, y + i);

        int ans = 1LL * n * (n - 1) * (n - 2) / 6;
        for(int i = 1; i <= n; ++i) {
            memset(a, 0, sizeof a);
            for(int j = i + 1; j <= n; ++j) {
                int tx = x[i] - x[j], ty = y[i] - y[j];
                int g = __gcd(tx, ty);
                tx = tx / g + 200; ty = ty / g + 200;
                ans -= a[tx][ty];
                a[tx][ty]++;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}


E. Vanya and Brackets

题意: 给一个表达式 只有*和+ 最多只有15个* 插入一对括号使得表达式的新值最大

思路: 括号肯定要插到一对*之间啦~ 简单起见~ 我们首位添加一下1* 和 *1 更好算

然后枚举每对合法的*位置 算一下表达式的值 取最大的就好了

这里学习了一下题解的表达式计算方法~ 很赞~

参考code:

//
//  Created by TaoSama on 2015-06-19
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

string s;

long long cal(int l, int r) {
//  cout << l << ' ' << r << endl;
    long long in = 0, mul = s[l] - '0';
    for(int i = l + 1; i <= r; i += 2) {
        if(s[i] == '*') mul *= s[i + 1] - '0';
        else {
            in += mul;
//          cout << "mul: " << mul << endl;
            mul = s[i + 1] - '0';
        }
    }
    in += mul;
//  cout << "in: " << in << endl;

    long long ret = 0;
    mul = s[0] - '0';
    for(int i = 1; i < s.size(); i += 2) {
        if(i + 1 == l) {
            mul *= in;
//          cout << "turn: " << mul << endl;
            i = r - 1;
            continue;
        }
        if(s[i] == '*') mul *= s[i + 1] - '0';
        else {
            ret += mul;
            mul = s[i + 1] - '0';
        }
    }
    ret += mul;
    return ret;
}

int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    ios_base::sync_with_stdio(0);

    while(cin >> s) {
        s = "1*" + s; s = s + "*1";

        long long ans = -INF;
        for(int i = 0; i < s.size(); ++i) {
            if(s[i] != '*') continue;
            for(int j = i + 1; j < s.size(); ++j) {
                if(s[j] != '*') continue;
                ans = max(ans, cal(i + 1, j - 1)); //括号里的[]
            }
        }
        cout << ans << '\n';
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值