题目链接
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e3 + 10;
char str[N];
struct node
{
ll v;
char c;
node &operator + (const node &o)
{
v += o.v;
return *this;
}
node &operator * (const node &o)
{
v *= o.v;
return *this;
}
void Smax(const node &o)
{
node t = o;
ll a = 0, b = 0;
while (v)
a += v % 10, v /= 10;
while (t.v)
b += t.v % 10, t.v /= 10;
v = max(a, b);
}
};
inline int lv(char c)
{
if (c == '+')
return 2;
if (c == '*')
return 3;
if (c == ',') //逗号最低
return 1;
return 0;
}
queue<node> q;
stack<node> stk;
void ToRPN(char *s)
{
ll t = 0;
for (int i = 0; s[i]; ++i)
{
if (isdigit(s[i]))
{
if (!i || !isdigit(s[i - 1]))
t = s[i] - '0';
else
t = t * 10 + s[i] - '0';
if (!isdigit(s[i + 1]))
q.push({ t, 0 });
}
else if (s[i] == '(')
stk.push({ 0, s[i] });
else if (s[i] == ')')
{
while (stk.top().c != '(')
q.push(stk.top()), stk.pop();
stk.pop();
}
else if (!isalpha(s[i])) //不是Smax
{
while (!stk.empty() && lv(s[i]) < lv(stk.top().c))
q.push(stk.top()), stk.pop();
stk.push({ 0, s[i] });
}
}
while (!stk.empty())
q.push(stk.top()), stk.pop();
}
ll CalPRN()
{
while (!q.empty())
{
char c = q.front().c;
if (!c)
stk.push(q.front()), q.pop();
else
{
q.pop();
node lst = stk.top();
stk.pop();
node fst = stk.top();
stk.pop();
if (c == '+')
fst = fst + lst;
else if (c == '*')
fst = fst * lst;
else if (c == ',')
fst.Smax(lst);
stk.push(fst);
}
}
ll res = stk.top().v;
stk.pop();
return res;
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
scanf("%s", str);
ToRPN(str);
printf("%lld\n", CalPRN());
}
return 0;
}
状态压缩,使一列四个砖块对应权值1 2 4 8,令d[i][j]表示第i列状态为j的方案数量,画图可以发现合法状态只有0 3 6 9 12 15,其它状态都不会出现。
然后手写每个状态的转移。。不使用矩阵优化也可以100ms飘过。
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 997;
template<typename T1, typename T2> inline bool setmin(T1 &a, const T2 &b){ if (b >= a) return false; a = b; return true; }
template<typename T1, typename T2> inline bool setmax(T1 &a, const T2 &b){ if (b <= a) return false; a = b; return true; }
template<typename T1, typename T2> inline void addmod(T1 &a, const T2 &b){ a = (a + b) % MOD; }
const int N = 1e6 + 10;
int f[N][16]; //第i列状态为j的方案数
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
f[1][0] = 1; //第1列为空
for (int i = 1; i < N; ++i) //实际上合法状态只有0 3 6 9 12 15
{
addmod(f[i][0], f[i - 1][0] + f[i - 1][3] + f[i - 1][9] + f[i - 1][12] + f[i - 1][15]);
addmod(f[i][3], f[i - 1][0] + f[i - 1][12]);
addmod(f[i][6], f[i - 1][9]);
addmod(f[i][9], f[i - 1][0] + f[i - 1][6]);
addmod(f[i][12], f[i - 1][0] + f[i - 1][3]);
addmod(f[i][15], f[i - 1][0]);
}
int T;
cin >> T;
while (T--)
{
int n, m, k, l, r;
cin >> n >> m >> k;
l = m - 1, r = n - (k + m - 1);
printf("%d %d\n", f[l + 1][0], f[r + 1][0]); //输出下一列没溢出来的状态
}
return 0;
}
矩阵优化版1ms
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 997;
template<typename T1, typename T2> inline bool setmin(T1 &a, const T2 &b){ if (b >= a) return false; a = b; return true; }
template<typename T1, typename T2> inline bool setmax(T1 &a, const T2 &b){ if (b <= a) return false; a = b; return true; }
template<typename T1, typename T2> inline void addmod(T1 &a, const T2 &b){ a = (a + b) % MOD; }
struct Matrix
{
int m[10][10];
static const int N = 6; //阶数
Matrix(int v = 0)
{
memset(m, 0, sizeof(m));
if (v)
for (int i = 0; i < N; i++)
m[i][i] = v;
}
Matrix operator * (const Matrix &b)
{
Matrix t;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < N; k++)
t.m[i][j] = (t.m[i][j] + m[i][k] * b.m[k][j]) % MOD;
return t;
}
friend Matrix operator ^ (Matrix a, int n)
{
Matrix t(1);
while (n)
{
if (n & 1)
t = t * a;
a = a * a;
n >>= 1;
}
return t;
}
}tran;
//下标0 1 2 3 4 5
//状态0 3 6 9 12 15
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
tran.m[0][0] = tran.m[1][0] = tran.m[3][0] = tran.m[4][0] = tran.m[5][0] = 1;
tran.m[0][1] = tran.m[4][1] = 1;
tran.m[3][2] = 1;
tran.m[0][3] = tran.m[2][3] = 1;
tran.m[0][4] = tran.m[1][4] = 1;
tran.m[0][5] = 1;
int T;
cin >> T;
while (T--)
{
int n, m, k, l, r;
cin >> n >> m >> k;
l = m - 1, r = n - (k + m - 1);
Matrix a, b; //a[0][i]表示当前列状态为i的方案数
a.m[0][0] = b.m[0][0] = 1; //1列状态为0
a = a * (tran ^ l); //得到l+1项的0状态
b = b * (tran ^ r);
printf("%d %d\n", a.m[0][0], b.m[0][0]);
}
return 0;
}
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e4 + 10;
int n, m;
struct node
{
int v;
double p;
bool operator < (const node &o) const
{
return p < o.p;
}
};
vector<node> e[N];
double dis[N];
bool vis[N];
void dijkstra()
{
memset(dis, 0, sizeof(dis));
memset(vis, 0, sizeof(vis));
priority_queue<node> pq;
pq.push({ 1, 1 });
dis[1] = 1;
while (!pq.empty())
{
int u = pq.top().v; pq.pop();
vis[u] = 1;
for (auto it : e[u])
{
int v = it.v;
double p = it.p;
if (!vis[v] && dis[v] < dis[u] * p)
dis[v] = dis[u] * p, pq.push({ v, dis[v] });
}
}
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
cin >> n >> m;
for (int i = 1; i <= n; ++i)
e[i].clear();
for (int i = 0; i < m; ++i)
{
int u, v;
double p;
scanf("%d%d%lf", &u, &v, &p);
e[u].push_back({ v, p / 100 });
e[v].push_back({ u, p / 100 });
}
dijkstra();
printf("%.6f\n", dis[n] * 100);
}
return 0;
}
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 2e3 + 10;
int x[N], y[N], r[N];
vector<int> e[N];
int n, X, Y, st, ed;
double ans = 0, S;
bool DFS(int x, int f)
{
if (x == ed)
{
ans += S / r[x];
return true;
}
for (int y : e[x]) if (y != f)
if (DFS(y, x))
{
ans += S / r[x];
return true;
}
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
cin >> n >> X >> Y;
for (int i = 1; i <= n; ++i)
{
scanf("%d%d%d", &x[i], &y[i], &r[i]);
if (x[i] == 0 && y[i] == 0)
st = i;
else if (x[i] == X && y[i] == Y)
ed = i;
e[i].clear();
}
S = r[st] * 10000;
for (int i = 1; i <= n; ++i)
for (int j = 1; j < i; ++j)
if ((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) == (r[i] + r[j]) * (r[i] + r[j]))
e[i].push_back(j), e[j].push_back(i);
ans = 0;
DFS(st, 0);
printf("%d\n", (int)(ans + 1e-6));
}
return 0;
}
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
string a, b;
cin >> a >> b;
set<ll> st;
for (int i = 0; i < a.size(); ++i) //位置
for (int j = 0; j < 2; ++j)
{
string c = a;
c[i] = j + '0';
if (c != a)
st.insert(stoll(c, 0, 2));
}
for (int i = 0; i < b.size(); ++i) //位置
for (int j = 0; j < 3; ++j)
{
string c = b;
c[i] = j + '0';
if (c != b)
{
ll res = stoll(c, 0, 3);
if (st.find(res) != st.end())
{
cout << res << endl;
goto brk;
}
}
}
brk: continue;
}
return 0;
}
#include
#include
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
struct node
{
int v;
node *l, *r;
}t[100];
void Insert(node *f, int v)
{
if (v < f->v)
{
if (f->l)
Insert(f->l, v);
else
f->l = new node{ v, 0, 0 };
}
else
{
if (f->r)
Insert(f->r, v);
else
f->r = new node{ v, 0, 0 };
}
}
bool equal(node *a, node *b)
{
if (!a && !b)
return true;
if (!a && b || a && !b)
return false;
if (a->l && !equal(a->l, b->l))
return false;
if (a->r && !equal(a->r, b->r))
return false;
return true;
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
{
int x;
scanf("%d", &x);
t[i] = { x, 0, 0 };
for (int j = 1; j < m; ++j)
{
int x;
scanf("%d", &x);
Insert(&t[i], x);
}
}
int k = 0;
for (int i = 1; i <= n; ++i)
{
int flag = 1;
for (int j = 1; j < i; ++j)
if (equal(&t[i], &t[j]))
flag = 0;
if (flag)
++k;
}
cout << k << endl;
}
return 0;
}