Codeforces Round #764 (Div. 3)

A. Plus One on the Subset
B. Make AP
C. Division by Two and Permutation
D. Palindromes Coloring
E. Masha-forgetful
F. Interacdive Problem
G. MinOr Tree


就是最小值逐步增加到最大值的过程。

int main()
{
	int t;
	scanf("%d", &t);
	for(int _ = 1;_ <= t;_ ++)
	{
		int n, mi = 1e9, ma = 0, x;
		scanf("%d", &n);
		while(n --) scanf("%d", &x), mi = min(mi, x), ma = max(ma, x);
		cout<<ma-mi<<endl;
	}
	return 0;
}

暴力枚举吧。

int main()
{
	int t;
	scanf("%d", &t);
	for(int _ = 1;_ <= t;_ ++)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		if((a+c&1) == 0 && (a+c>>1)%b == 0) P(1);
		else if(2*b > c && (2*b-c)%a == 0) P(1);
		else if(2*b > a && (2*b-a)%c == 0) P(1);
		else P(0);
	}
	return 0;
}

一颗二叉树,贪心从上往下,写麻烦了,下面有简单的。哎

// 额,很难看。。。。
int main()
{
	int t;
	scanf("%d", &t);
	for(int _ = 1;_ <= t;_ ++)
	{
		int n;
		scanf("%d", &n);
		for(int i = 0;i <= n;i ++) num[i] = 0;
		for(int i = 1;i <= n;i ++)
		{
			int x;
			scanf("%d", &x);
			while(x > n) x >>= 1;
			num[x] ++;
		}
		for(int i = n;i >= 1;i --)
		{
			if(!num[i]){
				for(int j = i+1;j <= n;j ++)
					if(num[j] > 1){
						int t = j;
						while(t > i) t >>= 1;
						if(t == i){
							num[j] --, num[i] = 1;
							break;
						}
					}
				if(!num[i]){num[0] = 1;break;}
			}
		}
		P(!num[0]);
	}
	return 0;
}

// 简化的。
#define P(x) puts((x)?Y1:N1)
#define Y1 "YES"
#define N1 "NO"
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N = 1e6+10;
 
int num[N];
bool dis[N];
 
int main()
{
	int t;
	scanf("%d", &t);
	for(int _ = 1;_ <= t;_ ++)
	{
		int n;
		scanf("%d", &n);
		for(int i = 0;i <= n;i ++) dis[i] = 0;
		for(int i = 1;i <= n;i ++)
		{
			scanf("%d", num+i);
			while(num[i] > n) num[i] >>= 1;
		}           
		sort(num+1, num+n+1);
		for(int i = n;i >= 1;i --)
		{
			while(num[i] && dis[num[i]]) num[i] >>= 1;
			dis[num[i]] = 1;
			if(!num[i]) i = 0; 
		}
		P(!dis[0]);
	}
	return 0;
}

直接分配,

int num[26];
char c[N];
 
int main()
{
	int t;
	scanf("%d", &t);
	for(int _ = 1;_ <= t;_ ++)
	{
		int n, k;
		scanf("%d%d%s", &n, &k, c);
		for(int i = 0;i < 26;i ++) num[i] = 0;
		for(int i = 0;c[i];i ++) num[c[i]-'a'] ++;
		int l = 0, r = 0;
		for(int i = 0;i < 26;i ++) l += num[i]>>1, r += num[i]&1;
		r += (l%k)*2; // 这句要加上。 
		l = l/k*2; 
		if(r >= k) l++;
		printf("%d\n", l);
	}
	return 0;
}

不要求最小数目那就可以把 > 3的段 分成 2*x + 3的形式。
 先dp一下看可不可以,可以就直接搜索


bool dis[N];
int num[1401];
PII p[1401];
string c;

int s(string c){int x = 0;for(auto v:c) x = x*11 + (v-'0'+1); return x;} // 映射成12进制的数 001 != 01 

void dfs(int i, int x)
{
	int t = 0, len = i + 1;
	if(i == 1 || i == 2)                        printf("%d\n", x+1);
	else if(dis[i-2]&&num[s(c.substr(i-1, 2))]) dfs(i-2, x+1), len = 2;
	else                                        dfs(i-3, x+1), len = 3;
	
	t = s(c.substr(i-len+1, len));
	printf("%d %d %d\n", p[t].first, p[t].second, num[t]);
	return ;
}
void p1(){puts("-1");return ;}

int main()
{
	int t;
	scanf("%d", &t);
	for(int _ = 1;_ <= t;_ ++)
	{
		int n, k;
		scanf("%d%d", &n, &k);
		for(int j = 1;j <= n;j ++)
		{
			cin>>c;
			for(int l = 2, x;l <= 3;l ++) 
				for(int i = 0;i <= k-l;i ++)
					x = s(c.substr(i, l)), num[x] = j, p[x] = {i+1, i+l};
		}
		cin>>c;
		dis[1] = num[s(c.substr(0, 2))]; dis[2] = num[s(c.substr(0, 3))];
		for(int i = 3;i < k;i ++)  // dp 一下  
			dis[i] = (dis[i-2]&&num[s(c.substr(i-1, 2))])|(dis[i-3]&&num[s(c.substr(i-2, 3))]);
		
		dis[k-1] ? dfs(k-1, 0): p1();  // p1 就是为了可以用 ? : 语句 
		for(int x = 0;x <= 1400;x ++) num[x] = dis[x] = 0;
	}
	return 0;
}

模拟,想成一个线段,每次可以把中点放到整除的位置从而把线段减半,然后注意要把mid+1放到整除的位置,因为最后mid = l

int main()
{
	int n;
	scanf("%d", &n);
	int l = 1, r = n-1, t = r-mid; 
	while(l < r)
	{
		int x;
		cout<<"+ "<<t<<endl;
		fflush(stdout);	
		scanf("%d", &x);
		l += t, r += t;
		x == r/n ? (l = r/n*n, t = (x+1)*n-mid-1) : (r = r/n*n-1, t = r-mid); 
	}
	cout<<"! "<<l<<endl; 
	return 0;
}

看答案的,贪心来算。哎

const int N = 1e6+10;
 
vector<PII>G[N];
bool dis[N];
int ans = 0, t = 0;
void dfs(int u)
{
	dis[u] = 1;
	for(auto x : G[u])
		if(!dis[x.first] && (ans|x.second) == ans)
			dfs(x.first);
	return ;
}
 
void add(){int u, v, w;scanf("%d%d%d", &u, &v, &w);G[u].push_back({v, w});G[v].push_back({u, w});}
void solve()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1;i <= n;i ++) G[i].clear();
	while(m --)add();
	t = 1<<29, ans = (1<<30)-1;
	while(t)
	{
		ans -= t;
		dfs(1);
		for(int i = 2;i <= n;i ++) dis[1] &= dis[i];
		if(!dis[1]) ans |= t; 
		memset(dis, 0, n+3);
		t >>= 1;
	}
	printf("%d\n", ans);
	return ;
}
int main()
{
	int t;
	scanf("%d", &t);
	while(t --) solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昌荣。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值