题目链接
C. Kamal-ol-molk's Painting
题意:给你n*m的字符串矩阵,含有'X' 和'.' 现在你要求一个a*b矩形的刷子,每次只能向右走或者向下走,问能否将所有的'X’都刷一遍。
做法:暴力枚举a 和b的长度,然后暴力模拟即可,注意这里的时间复杂度应该是n方到n^3/2之间
代码参考:传送门
#include <bits/stdc++.h>
using namespace std;
const int N = 1000 + 10;
char g[N][N];
int n, m, minX, minY, ans;
int sum[N][N], cnt, tot;
int getSum(int a, int b, int x, int y) {
return sum[a][b] - sum[a][y + 1] - sum[x + 1][b] + sum[x + 1][y + 1];
}
int ok(int a, int b) {
int posX =minX,posY=minY;
while(1) {
if(posX+a-1>n||posY+b-1>m) return 0;
if(getSum(posX,posY,posX+a-1,posY+b-1)!=a*b) return 0;
if(getSum(posX,posY,n,m)==a*b&&getSum(posX,posY,posX+a-1,posY+b-1)==a*b) {
return (cnt+a*b==tot);//终点,有可能在中间停止
}
bool flag1 = (a * b) == getSum(posX+1,posY,posX+a,posY+b-1);//向右走一格
bool flag2 = (a * b) == getSum(posX,posY+1,posX+a-1,posY+b);//向下走一格
if(!flag1&&!flag2) return 0;
if(flag1&&flag2) return 0;
if(flag1) ++posX,cnt+=b;//向右走一格,cnt总数等于列的个数
else ++posY,cnt+=a;
}
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
scanf("%s", g[i] + 1);
}
minX = n + 1, minY = m + 1;
ans = n * m + 1;
for(int i=n;i>0;--i){
for(int j=m;0<j;--j) {
sum[i][j] = sum[i][j] - sum[i + 1][j + 1] + sum[i + 1][j] + sum[i][j + 1] + (g[i][j] == 'X');
if(g[i][j] == 'X') {
minX = min(i, minX), minY = min(j, minY);
++tot;
}
}
}
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
if(ans <= i * j) continue;
cnt = 0;
if(ok(i, j)) ans = i * j;
}
}
printf("%d\n", ans == n * m + 1 ? -1 : ans);
return 0;
}
D. CGCDSSQ
题意:给你n长度的数组ai,接下来q次询问,输入x 问有多少个区间的gcd等于x
做法:dp[i][j]代表以i结尾的gcd为j的个数,由于gcd的特殊性质,j的个数不会超过log(a[i])个,所以map保存一下,暴力跑一遍就可以了。。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e5+10;
map<int,ll>mp1,mp2,ans;
int n,a[N],q;
int main()
{
cin>>n;
rep(i,1,n) scanf("%d",&a[i]);
for(int i=1;i<=n;++i){
swap(mp1,mp2);
mp2.clear();
for(auto it:mp1){
mp2[__gcd(it.first,a[i])]+=it.second;
}
mp2[a[i]]++;
for(auto it:mp2){
ans[it.first]+=it.second;
}
}
int q;cin>>q;while(q--)
{
int x;
scanf("%d",&x);
printf("%lld\n",ans[x]);
}
}