WEEEEEK16

文章提供了几个C++代码示例,分别用于检查两个数是否能被整数平方因子分解,计算序列中相同数字的最长连续长度,根据给定数字计算特定条件下的累加和,以及解决与数字模式相关的数学问题。这些代码涉及到了数论、算法和数据结构的应用。
摘要由CSDN通过智能技术生成

思路:

记录所有因子出现的次数,如果有因子出现了两次及以上,说明可以 分解为整数的平方的整数倍。代码如下。

#include <cstdio>
#include <set>
#include<iostream>
#include<cmath>
#include <queue>
#include <utility>
#include <algorithm>
#include <map>
using namespace std;
int gcd(int x, int y)
{
	int tmp;
	if (x < y)
	{
		tmp = x;
		x = y;
		y = tmp;
	}
	while (y > 0)
	{
		tmp = x % y;
		x = y;
		y = tmp;
	}
	return x;
}

map<long long, long long >tt;

void check(long long a)
{
	for (long long i = 2; i * i <= a; i++)
	{
		if(a%i==0)
		{
			tt[i]++;
			tt[a / i]++;
		}
	}
}
int main()
{
	bool flag = 0;
	long long n,m,t;
	cin >> n >> m;
	if (n == m)
	{
		cout << "no credit"; return 0;
	}
	check(n), check(m);
	for (auto it = tt.begin(); it != tt.end(); it++)
	{
		long long a = sqrt(it->first);
		if (a * a == it->first || it->second > 1)
		{
			flag = 1;
			break;
		}
	}
	if (tt.size() == 0)
	{
		cout << "full credit";
	}
	else if (flag == 0 || n * m == 1)
	{
		cout << "partial credit";
	}
	else cout << "no credit";


	return 0;
}

思路:从后向前,如果是相同的数,则将已有长度加一,可以继续;如果不同,则将已有长度乘二;代码如下

#include <cstdio>
#include <set>
#include<iostream>
#include<cmath>
#include <queue>
#include <utility>
#include <algorithm>
#include <map>
using namespace std;


int num[500005],n,t;
int main()
{
	scanf("%d",&t);
	for (int ii = 0; ii < t; ii++)
	{
		scanf("%d",&n);
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &num[i]);
		}
		int flag = num[n], ans = 0,cnt=1;
		num[0] = flag;
		for (int i = n; i >= 2; i--)
		{
			if (num[i] == flag && num[i - 1] != flag)
			{
				i -= cnt;
				if(i>0)num[i] = flag;
				cnt *= 2;
				ans += 1;
				i++;
			}
			else cnt++;
		}
		printf("%d\n",ans);
	}


	return 0;
}

 

用map装载不同数字出现的次数 ,然后遍历已经出现的数字,累加出现过数字的次数乘以比该数字 大c的数字;

#include <cstdio>
#include <set>
#include<iostream>
#include<cmath>
#include <queue>
#include <utility>
#include <algorithm>
#include <map>
using namespace std;


int n;
long long c;
map<long long, long long>m;
int main()
{
	scanf("%d%lld", &n, &c);
	long long ans = 0;
	long long tmp;
	set<long long>s;
	for (int ii = 0; ii < n; ii++)
	{
		scanf("%lld", &tmp);
		m[tmp]++;
		s.insert(tmp);
	}
	for (auto it = s.begin(); it != s.end(); it++)
	{
		long long cur = *it;
		ans += m[cur] * m[cur + c];
	}
	printf("%d", ans);
	return 0;
}

思路:把不同位数的数分为不同的区间,当位数为一或二时可以特判; 

#include <cstdio>
#include <set>
#include<iostream>
#include<cmath>
#include <queue>
#include <utility>
#include <algorithm>
#include <map>
using namespace std;
long long mod = 998244353;

int main()
{
	unsigned long long n, mul = 10, ans = 0;
	cin>>n;
	while (1)
	{
		if (n == 10 && mul == 10)
		{
			ans = 46;
			break;
		}
		else if (n <= 10 && mul == 10)
		{
			ans += (n + 1) * n / 2;
			break;
		}
		else if (n > 10 && mul == 10)
		{
			ans += 45;
		}
		else if (n > mul&&mul!=10)
		{
			unsigned long long x = (mul - mul / 10) % mod;
			unsigned long long y = (mul+1 - mul / 10) % mod;
			ans += (x * y) / 2 % mod;
		}
		else if (n < mul&&mul!=10)
		{
			unsigned long long x = (n+1 - mul / 10) % mod;
			unsigned long long y = (n + 2 - mul / 10) % mod;
			ans += (x * y) / 2 % mod;
			break;
		}
		mul *= 10;
	}
	cout << ans % mod << endl;
	return 0;
}

 思路:由于交换相邻的两个大臣不会对之前和之后的结果造成影响;

#include <cstdio>
#include <set>
#include<iostream>
#include<cmath>
#include <queue>
#include <utility>
#include <algorithm>
#include <map>
using namespace std;
int n, m, t;
int mod = 1000000007;
struct pep
{
	unsigned long long a, b;
};
bool cp(pep a, pep b)
{
	return (a.b * (b.a - 1) > b.b * (a.a - 1));
}
int main()
{
	scanf("%d", &n);
	pep p[1000005];
	for (int i = 0; i<n; i++)
	{
		scanf("%lld%lld", &p[i].a, &p[i].b);
	}
	sort(p, p + n, cp);
	unsigned long long mul[1000005];
	mul[n - 1] = 1;
	for (int i = n - 2; i >= 0; i--)
	{
		mul[i] = mul[i + 1] * p[i+1].a % mod;
	}
	unsigned long long ans = 0;
	for (int i = 0; i < n; i++)

	{
		ans += p[i].b * mul[i] % mod;
		ans% mod;
	}
	printf("%lld", ans % mod);
	return 0;
}

 运用到了快速求幂的技巧和离散数学中逆元的思想。

#include <cstdio>
#include <set>
#include<iostream>
#include<cmath>
#include <queue>
#include <utility>
#include <algorithm>
#include <map>
#include<stack>
using namespace std;
#define mode 1000000007
#define ll long long
#define N 1000005

ll qpow(ll a, ll n)
{
	ll ans = 1;
	while (n)
	{
		if (n & 1)
		{
			ans = ans * a % 1000000007;
		}
		a = a * a % 1000000007;
		n >>= 1;
	}
	return ans;
}
ll a, b, m, ans = 0;
ll f[N],nif[N];
ll c(ll a, ll b)
{
	return (f[a] * nif[b] %mode * nif[a - b] % mode) % mode;
}
int main()
{
	cin >> a >> b >> m;
	f[0] = 1, nif[0] = 1;
	ll ans = 0;
	for (ll i = 1; i < N; i++)
	{
		f[i] = i * f[i - 1] % mode;
	}
	nif[N - 1] = qpow(f[N - 1], mode - 2);
	for (ll i = N - 2; i >= 1; i--)
	{
		nif[i] = nif[i + 1] * (i + 1) % mode;
	}
	for (ll i = 0; i <= m; i++)
	{
		ll cnt = i * a + (m - i) * b;
		bool flag = 0;
		while (cnt)
		{
			if (cnt % 10 != a && cnt % 10 != b)
			{
				flag = 1; break;
			}
			cnt /= 10;
		}
		if (flag == 0)ans = (ans + c(m, i)) % mode;
	}
	cout << ans % mode;
	return 0;
}

 二分查找,但是由于有向上取整,所以精度要求较高,需要用double型进行判断,如果最后结果与强转为int型后的差值大于一个值,则可以认为需要进一;

#include <cstdio>
#include <set>
#include<iostream>
#include<cmath>
#include <queue>
#include <utility>
#include <algorithm>
#include <map>
#include<stack>
using namespace std;
#define mode 1000000007
#define ll long long
#define N 1000005

ll qpow(ll a, ll n)
{
	ll ans = 1;
	while (n)
	{
		if (n & 1)
		{
			ans = ans * a % 1000000007;
		}
		a = a * a % 1000000007;
		n >>= 1;
	}
	return ans;
}
int h[N];
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> h[i];
	}
	double l = 0, r = 100000000;
	double mid,e;
	bool fu = 0;
	while (l <= r)
	{
		fu = 0;
		mid = (l + r) / 2;
		e = mid;
		for (int i = 1; i <= n; i++)
		{
			e += e - h[i];
			if (e < 0)
			{
				fu = 1; break;
			}
		}
		if (fu == 1)
		{
			l = mid + 0.005;
		}
		else
		{
			r = mid - 0.005;
		}
	}
	if (mid - int(mid) > 0.01)mid += 1;
	cout << (int)mid;
	return 0;
}

简单的bfs捏。先把所i有可以到达的点都预处理一遍,最后统一输出即可。

#include <cstdio>
#include <set>
#include<iostream>
#include<cmath>
#include <queue>
#include <utility>
#include <algorithm>
#include <map>
#include<stack>
using namespace std;
#define mode 1000000007
#define ll long long
#define maxn 100000
#define N 100005

ll qpow(ll a, ll n)
{
	ll ans = 1;
	while (n)
	{
		if (n & 1)
		{
			ans = ans * a % 1000000007;
		}
		a = a * a % 1000000007;
		n >>= 1;
	}
	return ans;
}

int b[N],ans[N];
int a, q;
int vis[100005] = {0};
queue<int> que;
void bfs(int cur)
{
	que.push(cur);
	int tmp;
	while (!que.empty())
	{
		tmp = que.front();
		
		que.pop();
		
		if (tmp + 1 <= maxn&&!vis[tmp+1])
		{
			vis[tmp + 1] = vis[tmp] + 1;
			que.push(tmp + 1);
		}
		if (tmp - 1 >= 0 && !vis[tmp - 1])
		{
			vis[tmp - 1] = vis[tmp] + 1;
			que.push(tmp - 1);
		}
		if (tmp * 2 <= maxn && !vis[tmp * 2])
		{
			vis[tmp *2] = vis[tmp] + 1;
			que.push(tmp *2);
		}
		if (tmp *3 <= maxn && !vis[tmp *3])
		{
			vis[tmp *3] = vis[tmp] + 1;
			que.push(tmp *3);
		}

	}
	
	
}
int main()
{
	cin >> a >> q;
	
	for (int i = 0; i < q; i++)
	{
		cin >> b[i];
	}
	vis[a] = 1;
	bfs(a);
	for (int i = 0; i < q; i++)
	{
		cout << vis[b[i]]-1;
		if (i < q - 1)cout << ' ';
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值