题目链接:https://ac.nowcoder.com/acm/contest/6164#question
题解链接:
state 表示已经转了几次向,pre 记录的是当前的方向(上下表示-1,左右表示1),如果 pre * now == -1,表示转向了,转移时 state + 1
#include
using namespace std;
const int N = 105, INF = 0x3f3f3f3f;
char ma[N][N];
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int n, res = INF;
int sx, sy, gx, gy;
bool vis[N][N];
void dfs(int x, int y, int state, int pre)
{
// 不剪枝会TLE
if (state >= res) {
return;
}
if (x == gx && y == gy) {
res = min(res, state);
return;
}
int now;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (i < 2) now = -1;
else now = 1;
if (nx >= 0 && nx < n && ny >= 0 && ny < n && vis[nx][ny] == 0 && ma[nx][ny] != 'x') {
vis[nx][ny] = 1;
if (pre * now == -1) {
dfs(nx, ny, state + 1, now);
} else {
dfs(nx, ny, state, now);
}
vis[nx][ny] = 0;
}
}
}
int main(void)
{
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> ma[i][j];
if (ma[i][j] == 'A') {
sx = i, sy = j;
}
else if (ma[i][j] == 'B'){
gx = i, gy = j;
}
}
}
vis[sx][sy] = 1;
dfs(sx, sy, 0, 0);
cout << (res == INF ? -1 : res) << endl;
return 0;
}
题解:https://www.cnblogs.com/LinqiongTaoist/p/7203723.html
神奇的容斥原理,注意此时给出的数不是素数,所以计算重合的部分时,不能直接相乘,需要计算最小公倍数
#include
using namespace std;
typedef long long ll;
const int N = 20;
ll n, a, b, ans;
ll num[N];
// 最大公因数
ll gcd(ll a, ll b)
{
if (b == 0) return a;
return gcd(b, a % b);
}
// 最小公倍数
ll lcm(ll a, ll b)
{
return a * b / gcd(a, b);
}
void dfs(ll u, ll state, ll cnt)
{
// 安排了n个数
if (u == n) {
if (cnt % 2 == 0) {
ans += b/state - a/state;
} else {
ans -= b/state - a/state;
}
return;
}
// 剪枝
if (state > b) {
return;
}
// 选当前数
dfs(u + 1, lcm(state, num[u]), cnt + 1);
// 不选当前数
dfs(u + 1, state, cnt);
}
int main(void)
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> num[i];
cin >> a >> b;
a--;
dfs(0, 8, 0);
cout << ans << endl;
return 0;
}
类似于64位乘法,送温暖题
#include
#include
using namespace std;
typedef long long ll;
ll pow(ll k)
{
ll res = 0, x = 1;
while (k > 0) {
if (k & 1) res += x;
x *= 3;
k >>= 1;
}
return res;
}
int main(void)
{
int t, k, idx = 1;
cin >> t;
while (t--) {
cin >> k;
printf("Case #%d: %lld\n", idx++, pow(k));
}
return 0;
}