方格分割
从中心点开始dfs往外搜,标记搜过的点和对称的点,搜到边界就记录答案,最后去重除以4.
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
int ans;
int vis[8][8];
bool inside(int x, int y) {
if (x >= 0 && x <= 6 && y >= 0 && y <= 6)return true;
else return false;
}
void dfs(int x,int y)
{
//cout << x << " " << y << endl;
if (x == 0 || x == 6 || y == 0 || y == 6)
{
ans++;
return;
}
for (int i = 0; i < 4; i++)
{
if (inside(x + dx[i], y + dy[i]) && !vis[x + dx[i]][y + dy[i]])
{
vis[x + dx[i]][y + dy[i]] = 1;
vis[6 - x - dx[i]][6 - y - dy[i]] = 1;
dfs(x + dx[i], y + dy[i]);
vis[x + dx[i]][y + dy[i]] = 0;
vis[6 - x - dx[i]][6 - y - dy[i]] = 0;
}
}
}
void solve()
{
int x = 3, y = 3;
vis[3][3] = 1;
dfs(3, 3);
cout << ans / 4 << endl;
}
int main()
{
solve();
}
包子凑数
gcd 判断 是否全是倍数关系,如果全是倍数关系就说明有无穷多个解
然后用完全背包判断答案个数。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 110;
int a[N], vis[N * N], ans;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
void solve()
{
int n;
cin >> n;
int g = 0;
vis[0] = 1;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (g == 0) g = a[i];
else
{
g = gcd(g, a[i]);
}
for (int j = 0; j <= 10000; j++)
{
if(vis[j]) vis[j + a[i]] = 1;
}
}
if (g != 1) puts("INF");
else
{
for (int i = 1; i <= 10000; i++) if (!vis[i]) ans++;
cout << ans << endl;
}
}
int main()
{
solve();
}
分巧克力
可行解具有单调性,二分寻找最大值
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N = 1e5 + 10;
int h[N], w[N];
int n, k;
int check(int x)
{
int cnt = 0;
for (int i = 1; i <= n; i++)
{
cnt += (h[i] / x) * (w[i] / x);
}
if (cnt >= k) return 1;
else return 0;
}
void solve()
{
cin >> n >> k;
int l = 1, r = N;
for (int i = 1; i <= n; i++)
cin >> h[i] >> w[i];
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
cout << l << endl;
}
signed main()
{
solve();
}
购物单
一眼暴力
等差素数列
筛法筛出素数,遍历首项公差计算答案。
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N = 1e7 + 10;
bool vis[N];
int prime[N], cnt;
void get_prime(int n)
{
for (int i = 2; i <= n; i++)
{
if (!vis[i])
{
prime[cnt++] = i;
}
for (int j = 0; prime[j] <= n / i; j++)
{
vis[prime[j] * i] = 1;
if (i % prime[j] == 0) break;
}
}
}
void solve()
{
get_prime(N);
int cntt = 0;
for (int i = 2; i <= N; i++)
{
if (!vis[i])
{
for (int d = 1; d <= 10000; d++)
{
cntt = 1;
while (cntt != 10)
{
if (!vis[i + d * cntt])
{
//cout << i + d * cntt << " " << d << endl;
cntt++;
}
else break;
}
if (cntt == 10)
{
cout << d << endl;
return;
}
}
}
}
}
signed main()
{
solve();
}
承压计算
一眼
日期问题
用check函数分别判断abc分别为年月日的情况,符合条件输出。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<set>
#include<string>
#define int long long
using namespace std;
set<string> ans;
int a, b, c;
void check(int y, int m, int d)
{
bool flag = 0;
if (y >= 60) y = 1900 + y;
else y = 2000 + y;
if (m >= 1 && m <= 12)
{
if (d < 1) return;
if (m == 2)
{
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
{
if (d <= 29)
flag = 1;
}
else if (d <= 28) flag = 1;
}
else if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12)
{
if (d <= 31) flag = 1;
}
else
if (d <= 30) flag = 1;
if (flag)
{
string aa = "";
aa +=to_string(y) + "-";
if (m < 10) aa += "0";
aa += to_string(m) + "-";
if (d < 10) aa += "0";
aa += to_string(d);
ans.insert(aa);
}
}
}
void solve()
{
scanf("%lld/%lld/%lld", &a, &b, &c);
check(a, b, c);
check(c, b, a);
check(c, a, b);
for (auto x : ans)
cout << x << endl;
}
signed main()
{
solve();
}
k倍区间
前缀和,利用(s[n]-s[m])%k=0转化成s[n]%k=s[m]%k;
找出模k结果相同的对数
#include<iostream>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<set>
#include<string>
#define int long long
using namespace std;
const int N = 1e5 + 10;
set<string> ans;
int a[N], vis[N];
void solve()
{
int n, k, res = 0;
cin >> n >> k;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
a[i] = (a[i] + a[i - 1]) % k;
}
for (int i = 1; i <= n; i++) res += vis[a[i]]++;
res += vis[0];
cout << res << endl;
}
signed main()
{
solve();
}