D-迷宫:
这个题其实超简单的说,冷静下来仔细想一想,好好分析一下就直接就出来了
题目要求,按右下左上,无墙就必走,比如右无墙,此处就必须往右走
问添一些墙,让能够从 (1,1) 走到 (n,m)
简单画一下,不难发现如果往左或者往上走了,就会死循环在这来回走
那很简单,任何一个点只能是往右或者往下走得到的
写个dp记录添墙数,如果是往右走得到的点,那么就是直接转移墙数
如果是往下走得到的点,看前驱的右侧是不是墙,不是就添就+1,是就直接转移
思路非常简单,真不知道当时怎么想的
官方标程:
#include
using namespace std;
#define _rep(n, a, b) for (ll n = (a); n <= (b); ++n)
#define _rev(n, a, b) for (ll n = (a); n >= (b); --n)
#define _for(n, a, b) for (ll n = (a); n < (b); ++n)
#define _rof(n, a, b) for (ll n = (a); n > (b); --n)
#define oo 0x3f3f3f3f3f3f3f3fll
#define ll long long
#define db double
#define eps 1e-8
#define bin(x) cout << bitset<10>(x) << endl;
#define what_is(x) cerr << #x << " is " << x << endl
#define met(a, b) memset(a, b, sizeof(a))
#define all(x) x.begin(), x.end()
#define pii pair
#define pdd pair
const ll maxn = 1e3 + 100;
const ll mod = 1e9 + 7;
char mat[maxn][maxn];
ll dp[maxn][maxn];
signed main()
{
ll n, m;
cin >> n >> m;
met(dp, oo);
_rep(i, 1, n) cin >> (mat[i] + 1);
dp[1][1] = 0;
_rep(i, 1, n) {
_rep(j, 1, m) {
if (i == 1 && j == 1)continue;
if (mat[i][j] == '1')continue;
dp[i][j] = min(dp[i - 1][j] + (ll)(mat[i - 1][j + 1] == '0'), dp[i][j - 1]);
}
}
cout << (dp[n][m] >= oo ? -1 : dp[n][m]) << endl;
}
E:最大GCD
给数列a,q次查询,l r x 在l r中找一子区间[s,t]输出 max gcd(as ,as+1 ... , at, x),数据全是1e5范围内
这个题的手法其实挺常见的,没想到太不应该了
求一串数的最大公因子,从大到小遍历x的因子,当这个因子是公因子,以为着这串数都有这么个因子
你找子区间嘛
实际上只要找到一个因子在[l,r]里就可以了
就二分找到一个就行,非常的简单
#include
#include
using namespace std;
#define _rep(n, a, b) for (ll n = (a); n <= (b); ++n)
#define _rev(n, a, b) for (ll n = (a); n >= (b); --n)
#define _for(n, a, b) for (ll n = (a); n < (b); ++n)
#define _rof(n, a, b) for (ll n = (a); n > (b); --n)
#define oo 0x3f3f3f3f3f3fll
#define ll long long
#define db double
#define eps 1e-8
#define bin(x) cout << bitset<10>(x) << endl;
#define what_is(x) cerr << #x << " is " << x << endl
#define met(a, b) memset(a, b, sizeof(a))
#define all(x) x.begin(), x.end()
#define pii pair
#define pdd pair
#define pi acos(-1.0)
const ll maxn = 1e5 + 100;
const ll mod = 1e9;
vector pos[maxn], sons[maxn];
int n, q;
void pre_work()
{
_for(i, 1, maxn)
{
for (int j = 1; j * j <= i; ++j)
{
if (i % j == 0) {
sons[i].emplace_back(j);
if (i / j != j)sons[i].emplace_back(i / j);
}
}
sort(all(sons[i]), greater());
}
}
signed main()
{
ios::sync_with_stdio(0);
pre_work();
cin >> n >> q;
_rep(i, 1, n) {
int v;
cin >> v;
for (auto& c : sons[v]) {
pos[c].push_back(i);
}
}
_rep(i, 1, q) {
int l, r, x;
cin >> l >> r >> x;
for (auto s : sons[x]) {
int lll = lower_bound(pos[s].begin(), pos[s].end(), l) - pos[s].begin();
int rrr = upper_bound(pos[s].begin(), pos[s].end(), r) - pos[s].begin();
if (rrr > lll) {
cout << s << endl;
break;
}
}
}
}