1011 Random
签到
求一下期望 遇到0.5的时候求一下逆元就好了
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
typedef long long ll;
int a[N];
const int mod = 1e9 + 7;
ll qpow(ll m, ll k, ll p) {
ll res = 1 % p;
while (k) {
if (k & 1) res = res * m % p;
m = m * m % p;
k >>= 1;
}
return res;
}
ll inv(ll qwq) {
return qpow(qwq, mod - 2, mod);
}
void solve() {
int n; int m;
cin >> m;
cin >> n;
if (m == n) cout << 0 << endl;
else if ((m - n) & 1) {
cout << ((m - n) * inv(2) % mod) << endl;
}
else {
cout << (m - n) / 2 << endl;
}
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
1012 Alice and Bob
博弈
可以看出一开始序列有一个0的时候 Alice赢
假如序列中有2个1的时候 Alice也是赢的
再往后推可以发现 序列中有4个2的时候 Alice也是刚好赢的
再验证一个有8个3的时候 ,Alice是赢的
这个时候已经可以知道结论肯定是和 2的平方有关系的 然后在试试 一个1和两个2 发现这样也是可以的
然后从后往前循环一遍
a
[
i
−
1
]
+
=
a
[
i
]
/
2
a[i-1]+=a[i]/2
a[i−1]+=a[i]/2
最后判断一下
a
[
0
]
>
=
1
a[0]>=1
a[0]>=1 就好了
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const ll mod = 1e9+7;
void solve() {
int n;
cin >> n;
vector<int> v(n+2);
for (int i = 0; i <= n; i++) cin >> v[i];
for (int j = n; j > 0; j--) v[j-1] += v[j] / 2;
if (v[0]) cout << "Alice\n";
else cout << "Bob\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}
1003 Backpack
dp
求恰好装满背包的时候 求异或值最大
这道题刚开始想了两个小时的正向来写 ,用
d
p
[
i
]
dp[i]
dp[i] 来表示背包容量能到达 i 的各种异或值
但这显然就是不太行 异或的性质和相加不太一样 必须要全部存下来亦或值
想到了dp[i]来表示异或值为i的各种体积值 虽然好像这样看又回到了原来一样的问题
但因为体积值是相加的 这里面的一层可以用 bitset 来优化
最后记得清空 加上dp的时候要用滚动数组
#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define endl '\n'
const int N = 1e3 + 50;
typedef long long ll;
int a[N];
const int mod = 1e9 + 7;
int v[N], w[N];
void solve() {
bitset<1050> dp[5][N];//存在某个位置的重量
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> v[i] >> w[i];
}
//用dp[i][j]表示在第i论 异或值为j的体积的值
for (int i = 1; i <= n; i++) {
int p = i & 1, q = 1 ^ p;
dp[p][w[i]][v[i]] = 1;
for (int j = 1; j <= 1024; j++) {
dp[p][j] |= (dp[q][j ^ w[i]] << (v[i]));
}
for (int j = 1; j <= 1024; j++) {
dp[p][j] |= dp[q][j];
dp[q][j].reset();
}
}
int ans = -1;
for (int j = 0; j < 1024; j++) {
if (dp[n & 1][j][m]) {
ans = j;
}
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
1002 Dragon slayer
队友敲滴 好像是二进制枚举一下再加上模拟就行啦
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const ll mod = 1e9+7;
vector<pair<pii, pii>> walls;
const int MX = 50;
const int walk[][2] = {0, 2, 2, 0, 0, -2, -2, 0};
const int walk_ck[][2] = {0, 1, 1, 0, 0, -1, -1, 0};
int mp[MX][MX];
bool bfs(int n, int m, int sx, int sy, int ex, int ey, int wall) {
memset(mp, 0, sizeof(mp));
for (int i = 0; i < walls.size(); i++) {
if (wall & (1 << i)) {
int xs = min(walls[i].first.first, walls[i].second.first);
int xe = max(walls[i].first.first, walls[i].second.first);
for (int x = xs; x <= xe; x++) {
int ys = min(walls[i].first.second, walls[i].second.second);
int ye = max(walls[i].first.second, walls[i].second.second);
for (int y = ys; y <= ye; y++) {
mp[x][y] = -1;
}
}
}
}
for (int i = 0; i < n; i++) mp[i][0] = mp[i][m-1] = -1;
for (int i = 0; i < m; i++) mp[0][i] = mp[n-1][i] = -1;
queue<pii> q;
q.push({sx, sy});
while (!q.empty()) {
pii c = q.front(); q.pop();
if (c.first == ex && c.second == ey) {
return true;
}
for (int i = 0; i < 4; i++) {
int ncx = c.first + walk_ck[i][0];
int ncy = c.second + walk_ck[i][1];
int cx = c.first + walk[i][0];
int cy = c.second + walk[i][1];
if (ncx >= 0 && ncx < n && ncy >= 0 && ncy < m && cx >= 0 && cx < n && cy >= 0 && cy < m && mp[ncx][ncy] != -1 && mp[cx][cy] == 0) {
mp[cx][cy] = 1;
q.push({cx, cy});
}
}
}
return false;
}
void solve() {
int n,m, k;
cin >> n >> m >> k;
int sx,sy,ex,ey;
cin >> sx >> sy >> ex >> ey;
n *= 2; m *= 2;
n++; m++;
sx *= 2; sx++; sy *= 2; sy++;
ex *= 2; ex++; ey *= 2; ey++;
walls.clear();
for (int i = 0; i < k; i++) {
pair<pii, pii> w;
cin >> w.first.first >> w.first.second >> w.second.first >> w.second.second;
w.first.first *= 2; w.first.second *= 2;
w.second.first *= 2; w.second.second *= 2;
walls.push_back(w);
}
int ans = 15;
for (int i = 0; i < (1 << k); i++) {
if (bfs(n, m, sx, sy, ex, ey, i)) {
ans = min(ans, k - __builtin_popcount(i));
}
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}
1009 Laser
随机过的!!!
队友说随机过啦 !脑瓜子嗡嗡的!
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const double eps = 1e-8;
const double PI = acos(-1.0);
int sgn(double x) {
if (fabs(x) < eps) {
return 0;
}
return (x < 0) ? -1 : 1;
}
struct Point {
ll x, y;
Point(ll x = 0.0, ll y = 0.0): x(x), y(y) {}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B) {
return Vector(A.x + B.x, A.y + B.y);
}
Vector operator - (Point A, Point B) {
return Vector(A.x - B.x, A.y - B.y);
}
Vector operator * (Vector A, double p) {
return Vector(A.x * p, A.y * p);
}
Vector operator / (Vector A, double p) {
return Vector(A.x / p, A.y / p);
}
bool operator < (const Point A, const Point B) {
return A.x < B.x || (sgn(A.x - B.x) == 0 && A.y < B.y);
}
bool operator == (const Point A, const Point B) {
return sgn(A.x - B.x) == 0 && sgn(A.y - B.y) == 0;
}
double Dot(Vector A, Vector B) {
return A.x * B.x + A.y * B.y;
}
double Cross(Vector A, Vector B) {
return A.x * B.y - A.y * B.x;
}
double Length(Vector A) {
return sqrt(Dot(A, A));
}
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
Vector u = P - Q;
double t = Cross(w, u) / Cross(v, w);
return P + v * t;
}
int parallel(Point ua, Point ub,Point va, Point vb)//等于0说明向量平行
{
return ((ua.x-ub.x)*(va.y-vb.y)-(va.x-vb.x)*(ua.y-ub.y));
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inline int suiji(const int &l,const int &r){
return uniform_int_distribution<int>(l, r)(rng);
}
const ll mod = 1e9+7;
bool check(vector<Point> &vp, Point s, int n) {
for (int i = 0; i < n; i++) {
auto it = vp[i];
if (!sgn(it.x - s.x) || !sgn(it.y - s.y)) continue;
if (sgn(fabs(it.x - s.x) - fabs(it.y - s.y))) return false;
}
return true;
}
void solve() {
int n;
cin >> n;
vector<Point> v(n);
bool flag = true;
for (int i = 0; i < n; i++) {
cin >> v[i].x >> v[i].y;
if (i >= 2) {
flag = flag && parallel(v[i], v[i-1], v[i-1], v[i-2]) == 0;
}
}
if (flag) {
cout << "YES\n";
return;
}
for (int i = 0; i < n; i++) {
v.push_back({v[i].x, v[i].y - 1});
v.push_back({v[i].x-1, v[i].y});
v.push_back({v[i].x-1, v[i].y - 1});
v.push_back({v[i].x+1, v[i].y - 1});
}
int SUIJI_CNT = 1000;
for (int i = 0; i < SUIJI_CNT; i++) {
int a1 = suiji(0, n - 1);
int a2 = suiji(0, v.size() - 1);
if (a1 == a2) continue;
int b1 = suiji(0, n - 1);
int b2 = suiji(0, v.size() - 1);
if (b1 == b2) continue;
if (parallel(v[a1], v[a2], v[b1], v[b2]) == 0) continue;
Point p = GetLineIntersection(v[a1], v[a2] - v[a1], v[b1], v[b2] - v[b1]);
if (check(v, p, n)) {
cout << "YES\n";
return;
}
}
cout << "NO\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}