杭电多校第三场

hdu-6976
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 9;
int n, xa, xb, ya, yb;
pair <int,int> p[maxn];
int f[maxn];
void work()
{
	cin >> n;
	for(int i = 1; i <= n; ++i)
	{
		scanf("%d %d %d %d", &xa, &ya, &xb, &yb);
		int dx = xa - xb, dy = ya - yb;
		if(!dx) dy = 1;
		else if(!dy) dx = 1;
		else
		{
			if(dx < 0) dx = -dx, dy = -dy;// 为了让斜率相等的排序后是连着的 
			int d = __gcd(abs(dx), abs(dy));
			dx /= d; dy /= d;
		}
		p[i] = pair<int,int> (dx, dy);
	}
	sort(p + 1,p + 1 + n);
	for(int i = 1; i <= n; ++i) f[i] = 0;
	for(int i = 1, j; i <= n; i = j)
	{
		for(j = i; j <= n && p[i] == p[j]; ++j);
		for(int k = 1; k <= j - i; ++k) f[k]++;
	}
	int i = 1, j = 1;
	for(; i <= n; i++)
	{
      while(!f[j]) j++;
      f[j]--;
      printf("%d\n",i - j);
    }
}

int main()
{
	int T;cin>>T;while(T--)
	work();
	return 0;
}

hdu-6979
只读题感觉题意不是特别好懂,结合样例比较好理解
在这里插入图片描述
这个题关键是询问区间内,是否有mi = 1 的图层。

  1. 如果没有,答案就是l-r之间的前缀和(当然最大不能超过255
  2. 如果有,答案就是最右侧的 mi = 1的图层到 r 之间的前缀和

设置一个 f 数组,存左侧离 i 最近的 mi = 1的图层的位置

输出%x 是小写字母 %X是大写字母

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 9;
int r[maxn], g[maxn], b[maxn], f[maxn];
inline int ask(int a[], int l, int r)
{
	int x = f[r], res;// x是左侧离r最近的mi=1的图层,没有x就=0
	if(x < l) res = a[r] - a[l-1];// 区间内没有mi=1的图层
	else res = a[r] - a[x-1];
	return min(res, 255);
}
void work()
{
	memset(f, 0, sizeof(f));
	int n, q, m;
	cin >> n >> q;
	for(int i = 1;  i <= n; ++i)
	{
		scanf("%d %2X %2X %2X", &m, &r[i], &g[i], &b[i]);
		r[i] += r[i-1], g[i] += g[i-1], b[i] += b[i-1];
		if(m == 1) f[i] = i;
		else f[i] = f[i-1];
	}
	for(int i = 1; i <= q; ++i)
	{
		int x, y;
		scanf("%d %d", &x, &y);
		printf("%02X%02X%02X\n",ask(r,x,y),ask(g,x,y),ask(b,x,y));
		// 不足位数用0补齐,没有0表示用空格补齐
	}
}

int main()
{
	int T;cin>>T;while(T--)
	work();
	return 0;
}

hdu-6983
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map <ll, ll> ma;
ll n, k;
ll f(ll x)//  x是区间长度
{
	if(ma[x]) return ma[x];
	if(x <= k) return ma[x] = 1;
	else return ma[x] = f(x / 2) + f(x - x / 2) + 1;
}
void work()
{
	ma.clear();
	cin >> n >> k;
	cout << f(n) << endl;
}

int main()
{
	int T;cin>>T;while(T--)
	work();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值