有 n ∗ n n*n n∗n 的方格棋盘,现有黄蓝两种颜色,一圈一圈的图色,使得上一圈与下一圈相邻。试问总共最少要多少回合?
手动写几个找找规律。
int n, m;
int main()
{
int T;
sd(T);
while (T--)
{
sd(n);
pd(n / 2 + 1);
}
return 0;
}
n n n 块木板,再 q q q 次询问的情况下(询问时会添加或者减少木板),问在当前询问下是否能使用现有的木板构成一个正方形和一个矩形(也可以是正方形)?构成的时候,每一条边是只能用一块木板。
统计每个长度出现的次数,判断相同长度的个数是否为 2 2 2 的倍数或者 4 4 4 的倍数
const int N = 1e5 + 50;
int x, cnt[N];
int main()
{
int n, q;
sd(n);
rep(i, 1, n)
{
sd(x);
cnt[x]++;
}
int cnt2 = 0, cnt4 = 0;
rep(i, 1, 100000)
{
cnt2 += cnt[i] / 2;
cnt4 += cnt[i] / 4;
}
sd(q);
while (q--)
{
char op[5];
ss(op + 1);
sd(x);
cnt2 -= cnt[x] / 2;
cnt4 -= cnt[x] / 4;
if (op[1] == '+')
cnt[x]++;
else
a[x]--;
cnt2 += a[x] / 2;
cnt4 += a[x] / 4;
if (cnt4 > 0 && cnt2 >= 4)
puts("YES");
else
puts("NO");
}
return 0;
}
给你一个数组,问你怎样摆放该数组中的数可以使得数组中相同数之间的距离的最小值最大。
找到出现次数最多的那个数的次数,如果总数是奇数并且出现次数最多的比总数一半还多或者总数是偶数出现次数最多的比一半多那么就是 0 0 0 。
接下来就是二分,二分每一组的数量,最后答案 − 1 -1 −1 。
const int N = 1e5 + 10;
int n, q;
int a[N], cnt[N];
bool judge(int mid)
{
int res = n / mid;
int tmp = res;
int sum = mid * res;
if (n % mid)
tmp++;
rep(i, 1, n)
{
if (cnt[i] > tmp)
return false;
sum -= min(res, cnt[i]);
}
return sum <= 0;
}
int main()
{
int T;
sd(T);
while (T--)
{
sd(n);
rep(i, 1, n)
cnt[i] = 0;
int maxn = 0;
rep(i, 1, n)
{
sd(a[i]);
cnt[a[i]]++;
maxn = max(maxn, cnt[a[i]]);
}
if ((n & 1) && maxn > (n / 2 + 1))
{
puts("0");
continue;
}
if ((n % 2 == 0) && maxn > n / 2)
{
puts("0");
continue;
}
int l = 1, r = n;
int ans = 0;
while (l <= r)
{
int mid = (l + r) >> 1;
if (judge(mid))
{
ans = mid;
l = mid + 1;
}
else
r = mid - 1;
}
ans--;
pd(ans);
}
return 0;
}
给你一个 n ∗ m n*m n∗m 的由字母组成的矩阵,,问你这个矩阵中有多少个“相同字母组成的菱形”。
每个菱形显然可以分为上三角和下三角拼成的
那么以这个格子为中心的最大菱形就是 m i n ( 最 大 上 三 角 , 最 大 下 三 角 ) min(最大上三角,最大下三角) min(最大上三角,最大下三角) 接下来就是 d p dp dp 最大上三角(下三角了)
我们令 l [ i ] [ j ] l[i][j] l[i][j] 表示 ( i , j ) (i,j) (i,j) 向左延伸的最大同色格子 r [ i ] [ j ] r[i][j] r[i][j] 表示 ( i , j ) (i,j) (i,j) 向右延伸的最大同色格子, m i d [ i ] [ j ] = m i n ( l [ i ] [ j ] , r [ i ] [ j ] ) mid[i][j]=min( l[i][j],r[i][j] ) mid[i][j]=min(l[i][j],r[i][j]) ,表示 ( i , j ) (i,j) (i,j) 为中心的一行最多作为哪个尺寸的三角。
那么最大上三角的转移方程是,当上面的格子和自己同色时 u p [ i ] [ j ] = m i n ( u p [ i − 1 ] [ j ] + 1 , m i d [ i ] [ j ] ) up[i][j]=min(up[i−1][j]+1,mid[i][j]) up[i][j]=min(up[i−1][j]+1,mid[i][j])
u p [ i − 1 ] [ j ] up[i−1][j] up[i−1][j] 表示接着上面的尺寸,自己这行再加大一个尺寸,但是不能超过 m i d [ i ] [ j ] mid[i][j] mid[i][j]
当上面的格子和自己不同色时, u p [ i ] [ j ] = 1 up[i][j]=1 up[i][j]=1。
const int N = 2010;
char s[N][N];
int l[N][N], r[N][N], mid[N][N];
int n, m, up[N][N], down[N][N];
int main()
{
int n, m;
sdd(n, m);
rep(i, 1, n)
{
rep(j, 1, m)
{
cin >> s[i][j];
}
}
rep(i, 1, n)
{
rep(j, 1, m)
{
if (s[i][j] == s[i][j - 1])
l[i][j] = l[i][j - 1] + 1;
else
l[i][j] = 1;
}
per(j, m, 1)
{
if (s[i][j] == s[i][j + 1])
r[i][j] = r[i][j + 1] + 1;
else
r[i][j] = 1;
mid[i][j] = min(l[i][j], r[i][j]); //横向的长
}
}
rep(i, 1, m)
{
rep(j, 1, n)
{
if (s[j][i] == s[j - 1][i])
up[j][i] = min(mid[j][i], up[j - 1][i] + 1);
else
up[j][i] = 1;
}
per(j, n, 1)
{
if (s[j][i] == s[j + 1][i])
down[j][i] = min(mid[j][i], down[j + 1][i] + 1);
else
down[j][i] = 1;
}
}
int ans = 0;
rep(i, 1, n)
{
rep(j, 1, m)
{
ans += min(up[i][j], down[i][j]);
}
}
pd(ans);
}