Codeforces Round 952 (Div. 4)

D. Manhattan Circle

 

 

思路: 给你一个n*m的字符阵,问曼哈顿园的圆心在哪里。每次碰到#就更新边缘距离,最后直接输出(l + r) / 2即可。

实例:

#include<bits/stdc++.h>
using namespace std;
#define N 2000005
#define mod 100003
#define inf 1e9+7
typedef long long ll;
ll n, m, t, cnt = 1, ans,num, sum, minn = inf, maxx = 0;
ll x, y, z;
ll s1, s2;
ll a[N], b[N], c[N], times[N], dp[N];
bool vis[N];
typedef pair<int, int>pii;
priority_queue<pii, vector<pii>, greater<pii>>q;
struct node {
	int a, b, c;
}f[N];
vector<ll>v;
set<ll>s;
map<ll, ll>mp;
ll gcd(ll a, ll b) {
	return b > 0 ? gcd(b, a % b) : a;
}

ll lcm(ll a, ll b) {
	return a * b / gcd(a, b);
}
int main()
{
	cin >> t;
	void solve();
	while (t--) {
	    solve();
	}
	return 0;
}

void solve() 
{
	cin >> n >> m;
	char s;
	int h=0, l=0;
	mp.clear();
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> s;
			if (s == '#') {
				h = i, l = j;
				mp[j]++;
			}
		}
	}
	sum = 0,num=0;
	for (int i = 1; i <= m; i++) {
		if (sum < mp[i]) {
			sum = mp[i];
			num = i;
		}
	}
	cout << h-sum/2  << " " << l << endl;
	/*cin >> n;
	ans = 0,sum=0;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		mp[a[i]]++;
	}
	for (int i = 1; i <= n; i++) {
		sum += a[i];
		if (sum % 2 == 0&&mp[sum/2]) {
			ans++;
		}
	}
	cout << ans << endl;*/
}

E. Secret Box

思路: 给你一个盒子,长宽高分别为x,y,z,给你一个体积K ,能否找到n,m,k,体积等于K,问在盒子中有多少种放法。因为数据范围是1~2000,枚举n和m,再算出k,看能否整除,最后求出(x - n + 1) *(y - m + 1) * (z - k + 1)的最大值即可。

实例:

#include<bits/stdc++.h>
using namespace std;
#define N 2000005
#define mod 100003
#define inf 1e9+7
typedef long long ll;
ll n, m, t, k, cnt = 1, ans, num, sum, minn = inf, maxx = 0;
ll x, y, z;
ll s1, s2;
ll a[N], b[N], c[N], times[N], dp[N];
bool vis[N];
typedef pair<int, int>pii;
priority_queue<pii, vector<pii>, greater<pii>>q;
struct node {
	int a, b, c;
}f[N];
vector<ll>v;
set<ll>s;
map<ll, ll>mp;
ll gcd(ll a, ll b) {
	return b > 0 ? gcd(b, a % b) : a;
}

ll lcm(ll a, ll b) {
	return a * b / gcd(a, b);
}
int main()
{
	cin >> t;
	void solve();
	while (t--) {
	    solve();
	}
	return 0;
}

void solve() 
{
	cin >> x >> y >> z >> k;
	ans = 0, sum = 0;
	for (int i = 1; i <= x; i++) {
		for (int j = 1; j <= y; j++) {
			if (k % (i * j)==0) {
				num = k / (i * j);
				sum = (x - i + 1) * (y - j + 1) * (z - num + 1);
				ans = max(ans, sum);
			}
		}
	}
	cout << ans << endl;
}

C. Good Prefixes

 

 

思路: 给你n个数字,问他的前缀能否满足最大的数字等于其他所有数字之和,统计可以满足的数量。枚举即可,每次用最大的数字和其他数字之和比较,统计答案即可。复杂度O(n)。

实例:

#include<bits/stdc++.h>
using namespace std;
#define N 2000005
#define mod 100003
#define inf 1e9+7
typedef long long ll;
ll n, m, t, cnt = 1, ans,num, sum, minn = inf, maxx = 0;
ll x, y, z;
ll s1, s2;
ll a[N], b[N], c[N], times[N], dp[N];
bool vis[N];
typedef pair<int, int>pii;
priority_queue<pii, vector<pii>, greater<pii>>q;
struct node {
	int a, b, c;
}f[N];
vector<ll>v;
set<ll>s;
map<ll, ll>mp;
ll gcd(ll a, ll b) {
	return b > 0 ? gcd(b, a % b) : a;
}

ll lcm(ll a, ll b) {
	return a * b / gcd(a, b);
}
int main()
{
	cin >> t;
	void solve();
	while (t--) {
	    solve();
	}
	return 0;
}

void solve() 
{
	cin >> n;
	for (int i = 1; i <= n; i++) 
		cin >> a[i];
	ans = 0, sum = a[1];
	dp[1] = a[1];
	if (a[1] == 0) 
		ans++;
	for (int i = 2; i <= n; i++)
	{
		dp[i] = dp[i - 1] + a[i];
		if (a[i] > sum) sum = a[i];
		if (dp[i] % 2==0)
		{
			if (dp[i] / 2 == sum) 
				ans++;
		}

	}
	cout << ans << endl;
}

F. Final Boss

 

思路: 给你一个n为大BOSS的血量值,再给你n组数字,每个数字有一个攻击值和冷却时间,每次攻击可以使用多个没有冷却的数字,问最少多少轮可以击败BOSS。直接枚举二分的边界,代表轮数,可以推断出,如果第n轮可以完成,那么n+1轮也一定完成,符合单调性,直接用二分,check询问能否打败BOSS即可

实例:

#include<iostream>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdlib.h>
#define ll long long
using namespace std;
const int N = 200010;
const int M = 100100;
const ll mod = 1e9+7;
 
ll w[N], v[N], f[N], cnt, n, m, t, dp[N], sum[N],a[N],c1=0,c2=0;
ll f1[M], f2[M];
ll next1[100010];
 
 
ll h;
bool check(ll mid)
{
    ll sum = 0;
    for (int i = 1; i <= n; i++)
    {
        ll cnt = (mid-1) / w[i]+1;
        if (cnt >= h) return true;
        sum += cnt * v[i];
    }
    return sum >= h;
}
void solve()
{
    
    cin >> h >> n;
    for (int i = 1; i <= n; i++) cin >> v[i];
    for (int i = 1; i <= n; i++) cin >> w[i];
    
    ll l = 1, r = 1e12;
    while (l < r)
    {
        ll mid = (l + r) / 2;
        if (check(mid))
        {
            r = mid;
        }
        else l = mid+1;
    }
    cout << l<<"\n";
}
int main()
{
    cin >> t;
    while(t--)
    solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值