codeforces#266 总结

我靠!写的东西总被坑爹又不稳定的博客频道吞掉,我已经无力吐槽,也无力再写了!

简单写写题意题解。

A:

题意:给出n,m,a,b,表示坐n次公交,有单程票和多程票,多程票能用m次,单程票a元,多程票b元,求最少花费。

题解:动规, f[i]表示坐i次时最小花费,转移注意点就好了。不细说了,看代码,水水的!

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1005
using namespace std;

int f[N];
int n,m,a,b;

int main()
{
	int i,j,k;
	scanf("%d%d%d%d",&n,&m,&a,&b);
	for(i=1;i<=n;i++)
	{
		f[i]=f[i-1]+a;
		for(j=max(0,i-m);j<i;j++)
		{
			f[i]=min(f[i],f[j]+b);
		}
	}
	printf("%d\n",f[n]);
	return 0;
}

B:

题意:给出n,a,b,增加a或者b中至多一个的权值,使a*b>=6*n,输出a*b的最小值,及此时的a和b(SPJ)

题解:看代码吧,我毕竟被坑没A。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

long long n,a,b,c,d;

int main()
{
	cin>>n>>a>>b;
	n=n*6ll;
	if(n<=a*b)
	{
		cout<<a*b;
		printf("\n");
		cout<<a<<' '<<b;
		printf("\n");
		return 0;
	}
	else
	{
		c=n/a;
		if(a*c<n)c++;
		d=n/b;
		if(b*d<n)d++;
		if(a*c<=b*d)
		{
			cout<<a*c;
			printf("\n");
			cout<<a<<' '<<c;
			printf("\n");
			return 0;
		}
		else
		{
			cout<<b*d;
			printf("\n");
			cout<<d<<' '<<b;
			printf("\n");
			return 0;
		}

	}
	return 0;
}

C:

题意:给出n个数,把它们不打乱顺序分成三份(每份都不为空),使每份权值相同,问有多少种分法。

题解:正向反向预处理出权值前缀后缀和、之前之后有多少次权值正好为总权值1/3 。然后正着枚举,若前缀和是总权值1/3,看之后有多少种分法。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define N 501000
using namespace std;

int n,a[N],ctl[N],ctr[N];
long long sum,suml[N],sumr[N];
long long ans;
int main()
{
	int i,j,k;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d",&a[i]),sum+=a[i];
	if(sum%3)
	{
		printf("0\n");
		return 0;
	}
	sum/=3;
	for(i=1;i<=n;i++)
	{
		suml[i]=suml[i-1]+a[i];
		ctl[i]=ctl[i-1];
		if(suml[i]==sum)ctl[i]++;
	}
	for(i=n;i;i--)
	{
		sumr[i]=sumr[i+1]+a[i];
		ctr[i]=ctr[i+1];
		if(sumr[i]==sum)ctr[i]++;
	}

	for(i=1;i<n-1;i++)
	{
		if(suml[i]==sum)ans+=ctr[i+2];
	}
	cout<<ans;
	return 0;
}

D :

题意:给n个数,要把它们通过规定操作全变成m,问有多少种方案。

操作:把一个区间上每个数都权值+1,任意两次操作的左端点不能相同,任意两次操作的左端点不能相同,如[1,5],[2,5]和[1,4],[2,4]这两例都不合法。

题解: 没AC,也不会。

E:

题意:n个文员,m次操作。

操作一:输入 a,b , 表示a的上司设定为b

操作二:输入 a    , 表示从a开始传递资料,a往其上司传,上司再往上一层传,一直到没上司为止。

操作三:输入 a,b , 表示询问文员a是否经手过资料b。

题解:(第四个点开始TLE)(觉得我的算法是O(n))

操作一为连边,b向a。

然后边有权值,为当前传过的资料号,

dfs时离线处理每次询问的答案,若传该资料的人到文员a的若干边的权值最大值大于资料号,则“NO”。小于则“YES”。

代码:可以去看我的tarjan lca,里面有这种算法的思想(自创)。

http://blog.csdn.net/vmurder/article/details/38734663

#include <cstdio>
#include <algorithm>
#define N 5001000
using namespace std;

struct KSD
{
	int v,len,next;
}e[N],eq[N];
int head[N],headq[N],cnt,cntq,dcount;
int crs[N],ans[N];
bool visit[N];
int n,m;
void add(int u,int v)
{
	e[++cnt].v=v;
	e[cnt].len=dcount;
	e[cnt].next=head[u];
	head[u]=cnt;
}
void addq(int u,int v,int len)
{
	eq[++cntq].v=v;
	eq[cntq].len=len;
	eq[cntq].next=headq[u];
	headq[u]=cntq;
}
int f[N],l[N];
inline int find(int x)
{
	if(f[x]==x)return x;
	int t=f[x];
	f[x]=find(f[x]);
	l[x]=max(l[x],l[t]);
	return f[x];
}
inline void dfs(int x,int p,int ll)
{
	int i;
	visit[x]=1;
	for(i=head[x];i;i=e[i].next)
	{
		dfs(e[i].v,x,e[i].len);
	}
	for(i=headq[x];i;i=eq[i].next)
	{
		if(find(eq[i].v)==x&&l[eq[i].v]<=eq[i].len)
		{
			ans[i]=1;
		}
	}
	f[x]=p;
	l[x]=ll;
}

int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k;
	int a,b,c;
	scanf("%d%d",&n,&m);
	dcount=1;
	for(i=1;i<=m;i++)
	{
		scanf("%d",&a);
		if(a==1)
		{
			scanf("%d%d",&b,&c);
			add(c,b);
		}
		if(a==2)
		{
			scanf("%d",&b);
			crs[dcount++]=b;
		}
		if(a==3)
		{
			scanf("%d%d",&b,&c);
			if(c>=dcount)++cntq;
			else addq(b,crs[c],c);
		}
	}
	for(i=1;i<=n;i++)f[i]=i;
	for(i=1;i<=n;i++)
	{
		if(!visit[i])dfs(i,i,0);
	}
	for(i=1;i<=cntq;i++)
	{
		if(ans[i])puts("YES");
		else puts("NO");
	}
	return 0;
}




时间: 2024-10-06 00:06:19

codeforces#266 总结的相关文章

Codeforces Round #266 (Div. 2)

Codeforces Round #266 (Div. 2) 题目链接 A:就简单的判断一下那种更大即可 B:枚举x到sqrt(n),然后可以直接算出y,然后判断一下即可 C:先判断和是否是3的倍数,然后预处理出前缀和出现位置和后缀和对应sum / 3个数,然后从头往后扫一遍把当前一个和后面进行组合即可 D:先预处理出差分,使得数组表示线段的添加方式,然后每次有一个-1,就能和前面多少个1进行匹配,方案数就乘上多少,如果是0,就能和前面+1个匹配 E:利用并查集,把每次询问拆分成2个部分,起点到

Codeforces Round #266 (Div. 2)B(暴力枚举)

很简单的暴力枚举,却卡了我那么长时间,可见我的基本功不够扎实. 两个数相乘等于一个数6*n,那么我枚举其中一个乘数就行了,而且枚举到sqrt(6*n)就行了,这个是暴力法解题中很常用的性质. 这道题找出a和b中最小的那个,然后开始枚举,一直枚举到sqrt(6*n)的向上取整.这样所有可能是答案的情况都有啦.再干别的都是重复的或者肯定不是最小面积的. #include<iostream> #include<cstdio> #include<cstdlib> #includ

Codeforces Round #266 (Div.2) B Wonder Room --枚举

题意:给出一个两边长为a,b的矩形,要求增加a和增加b使a*b>=6*n且a*b最小. 解法:设新的a,b为a1,b1,且设a<b,那么a<=a1<=ceil(sqrt(6*n)),那么我们可以枚举a1,然后算出b1,如果b1<b,那么b1 = b,然后算出面积,取所有面积的最小值不就可以了,然后再枚举一次b1,处理与之相同即可. 复杂度O(sqrt(n)) 代码: #include <iostream> #include <cstdio> #incl

Codeforces Round #266 (Div. 2) A

题目: A. Cheap Travel time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Ann has recently started commuting by subway. We know that a one ride subway ticket costs a rubles. Besides, Ann found ou

Codeforces Round #266 (Div. 2)C. Number of Ways

传送门 Description You've got array a[1], a[2], ..., a[n], consisting of n integers. Count the number of ways to split all the elements of the array into three contiguous parts so that the sum of elements in each part is the same. More formally, you nee

Codeforces Round #266 (Div. 2)-C,D

C - Number of Ways 直接暴力从前往后寻找.假设找到1/3sum的位置,那么标记++.找到2/3的位置,总数加上标记数. #include<stdio.h> #include<iostream> #include<stdlib.h> #include<string.h> #include<algorithm> #include<vector> #include<math.h> #include<que

Codeforces Round #266 (Div. 2) A. Cheap Travel

Ann has recently started commuting by subway. We know that a one ride subway ticket costs a rubles. Besides, Ann found out that she can buy a special ticket for m rides (she can buy it several times). It costs b rubles. Ann did the math; she will nee

Codeforces Round #266 (Div. 2) B. Wonder Room

The start of the new academic year brought about the problem of accommodation students into dormitories. One of such dormitories has a a?×?b square meter wonder room. The caretaker wants to accommodate exactly n students there. But the law says that

Codeforces Round #266 (Div. 2) D. Increase Sequence

Peter has a sequence of integers a1,?a2,?...,?an. Peter wants all numbers in the sequence to equalh. He can perform the operation of "adding one on the segment[l,?r]": add one to all elements of the sequence with indices froml to r (inclusive).