2022十三届蓝桥杯省赛赛时代码

1478
14

应该就是取模问题?

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>

using namespace std ;

const int N = 1e5 + 10 ;
typedef long long LL ;

LL a , b , n ;

int main(void)
{
	scanf("%lld%lld%lld" , &a , &b , &n) ;
	LL t = 5 * a + b * 2 ;
	LL ans = n / t * 7 ;
	n %= t ;
	if(n <= 5 * a) ans += (n + a - 1) / a ;
	else 
	{
		n -= 5 * a ;
		ans += 5 + (n + b - 1) / b ;
	}
	printf("%lld" , ans) ;
}

本来只有一行

printf("%d\n" , max((i - 1) * 2 , 2 * (n - i))) ;

后来考虑到有可能特判n = 1的情况,于是赋值

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std ;

const int N = 1e5 + 10 ;

int a[N] ;

int main(void)
{
	int n ;
	scanf("%d" , &n) ;
	for(int i = 1 ; i <= n ; i ++) a[i] = i ;
	for(int i = 1 ; i <= n ; i ++)
		printf("%d\n" , max(a[i] , max((i - 1) * 2 , 2 * (n - i)))) ;
}

X进制 , 就是简单的贪心,从低位向高位尽可能的选取最低的进制

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>

using namespace std ;

const int N = 1e5 + 10 ;
const int mod = 1e9 + 7 ;

int a[N] , b[N] ;
int ans ;

int get(int x)
{
	return (x % mod + mod) % mod ;
}
int main(void)
{
	int n , m ;
	int t ;
	scanf("%d" , &t) ;
	scanf("%d" , &n) ;
	for(int i = 1 ; i <= n ; i ++)	scanf("%d" , &a[i]) ;
	scanf("%d" , &m) ;
	for(int i = 1 ; i <= m ; i ++)  scanf("%d" , &b[i]) ;
	int i , j , res = 1 ;
	for(i = n , j = m ; i && j ; i -- , j --)
	{
		ans = (ans + res * 1ll * get(a[i] - b[j]) % mod) % mod ;
		res = (res * 1ll * max(2 , (max(a[i] , b[j]) + 1))) % mod ;
		cout << res << endl ;
	}
	while(i)
	{
		ans = (ans + res * 1ll * a[i] % mod) % mod ;
		res = (res * 1ll * max(a[i] + 1 , 2)) % mod ;
		i -- ;
	} 
	while(j)
	{
		ans = (ans + res * 1ll * b[j] % mod) % mod ;
		res = (res * 1ll * max(b[j] + 1 , 2)) % mod ;
		j -- ;
	}
	printf("%d" , ans) ;
}

应该是前缀和+尺取O(n^3)

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std ;

const int N = 5e2 + 10 ;
typedef long long LL ;

int g[N][N] ;
int n , m , k ;
LL ans ;

int get(int tx , int ty , int x , int y)
{
	return g[x][y] - g[x][ty - 1] - g[tx - 1][y] + g[tx - 1][ty - 1] ;
}

int main(void)
{
	scanf("%d%d%d" , &n , &m , &k) ;
	for(int i = 1 ; i <= n ; i ++)
		for(int j = 1 ; j <= m ; j ++)
			scanf("%d" , &g[i][j]) ;
	for(int i = 1 ;i <= n ; i ++)
		for(int j = 1 ; j <= m ; j ++)
			g[i][j] = g[i][j] + g[i - 1][j] + g[i][j - 1] - g[i - 1][j - 1] ;
	for(int i = 1 ; i <= n ; i ++)
		for(int j = i ; j <= n ; j ++)
		{
			for(int t = 1 , p = 1 ; t <= m ; t ++)
			{
				while(p <= t && get(i , p , j , t) > k) 
					p ++ ;
				ans += max(t - p + 1 , 0 ) ;
			}
		}	
	printf("%lld" , ans) ;
}

状压dp,枚举各种情况

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std ;

const int N = 1e7 + 10 ;
const int K = 4 ;
const int mod = 1e9 + 7 ;

int f[N][K] ;

int main(void)
{
	int n ;
	scanf("%d" , &n) ;
	f[0][3] = 1 ;
	for(int i = 1 ; i <= n ; i ++)
	{
		f[i][0] = f[i - 1][3] ;
		f[i][1] = (f[i - 1][2] + f[i - 1][0]) % mod ;
		f[i][2] = (f[i - 1][1] + f[i - 1][0]) % mod ;
		f[i][3] = ((f[i - 1][1] + f[i - 1][2]) % mod + (f[i - 1][3] + f[i - 1][0]) % mod) % mod ;
	}
	printf("%d" , f[n][3]) ;
}

唯一不会的题,只会暴力骗40,刚开始想并查集,后来发现问题,不可能是双向边于是改成dfs

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>

#define int long long 

using namespace std ;

const int N = 5e4 + 10 ;
const int M = 1e7 + 10 ;

int h[N] , e[M] , ne[M] , idx ;
bool st[N] ;

void add(int a , int b)
{
	e[idx] = b , ne[idx] = h[a] , h[a] = idx ++ ;
}

struct Node
{
	int x , y ;
	int r ;
} a[N] ;

int get_dist(int x , int y , int _x , int _y)
{
	int dx = x - _x ;
	int dy = y - _y ;
	return dx * dx + dy * dy ;
}

void dfs(int u)
{
	st[u] = true ;
	for(int i = h[u] ; ~ i ; i = ne[i])
	{
		int j = e[i] ;
		if(st[j]) continue ;
		dfs(j) ;
	}
}
signed main(void)
{
	memset(h , -1 , sizeof h) ;
	int n , m ;
	scanf("%lld%lld" , &n , &m) ;
	for(int i = 1 ; i <= n ; i ++)
		scanf("%lld%lld%lld" , &a[i].x , &a[i].y , &a[i].r) ;		
	for(int i = 1 ; i <= n ; i ++)
		for(int j = 1 ; j <= n ; j ++)
			if(i != j && get_dist(a[i].x , a[i].y , a[j].x , a[j].y) <= a[i].r * a[i].r)
				add(i , j) ;
	for(int i = 1 ; i <= m ; i ++)
	{
		int x , y , r ;
		scanf("%lld%lld%lld" , &x , &y , &r) ;
		for(int j = 1 ; j <= n ; j ++)
			if(!st[i] && get_dist(x , y , a[j].x , a[j].y) <= r * r)
				dfs(i) ;
	}
	int res = 0 ;
	for(int i = 1 ; i <= n ; i ++)
		if(st[i])
			res ++ ;
	printf("%lld" , res) ;
}

9.李白
这个三维dp即可
第一维是一共走了i步,剩下j个酒(酒不可能超过(n + m)) , 经过了k个店
由于最后一个必须是花而且刚好用完,所以输出f[n + m - 1][1][m]

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std ;

const int N = 1e2 + 10 ;
const int mod = 1e9 + 7 ;
const int M = 2e2 + 10 ;

int f[M][M][N] ;

int main(void)
{
	int n , m ;
	scanf("%d%d" , &n , &m) ;
	f[0][2][0] = 1 ;
	for(int i = 1 ; i <= n + m ; i ++)
		for(int j = 0 ; j <= n + m ; j ++)
			for(int k = 0 ; k <= n ; k ++)
			{
				f[i][j][k] += f[i - 1][j + 1][k] ;
				if(k && j % 2 == 0) f[i][j][k] += f[i - 1][j / 2][k - 1] ;
				f[i][j][k] %= mod ;	
			}
	printf("%d" , f[n + m - 1][1][n]) ;
}

这道题具有思维性,当时看到这个题我发现一个数最多变换6次就可以变成1,所以总次数一定不超过6n,暴力合并即可

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>

using namespace std ;

const int N = 1e5 + 10 ;

typedef long long LL ;

struct Segment
{
	int l , r ;
	LL val ;
	bool operator<(const Segment& t)const
	{
		if(val != t.val) return val < t.val ;
		return l > t.l ;
	}
};

priority_queue<Segment> q ;
LL a[N] ;

int main(void)
{
	int n ;
	scanf("%d" , &n) ;
	for(int i = 1 ; i <= n ; i ++)
		scanf("%lld" , &a[i]) ;
	for(int i = 1 ; i <= n ; i ++)
	{
		int j = i ;
		while(j <= n && a[j] == a[i]) j ++ ;
		q.push({i , j - 1 , a[i]}) ;
		i = j - 1 ;
	}
	int ans = 0 ;
	Segment t ;
	while(q.size() > 1 || q.top().val != 1)
	{
		t = q.top() ;
		q.pop() ;
		int res = 0 ;
		while(q.size() && t.r + 1 == q.top().l && t.val == q.top().val)
		{
			t.r = q.top().r ;
			q.pop() ;
			res ++ ;
		}
		t.val = (LL) sqrt(t.val / 2 + 1) ;
		q.push(t) ;
		if(q.size() > 1 || q.top().val != 1)
			ans ++ ;
	}
	LL r = 1e18 ;
	printf("%d" , ans) ;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值