signed main()
{
IO;
int t;cin >> t;
string ss = "codeforces";
while(t--)
{
string s;cin >> s;
int cnt = 0;
for(int i = 0;i < 10;i ++)
{
if(s[i] != ss[i])
cnt ++;
}
cout << cnt << endl;
}
return 0;
}
signed main()
{
IO;
int t; cin >> t;
while (t--)
{
int n; cin >> n;
vector a(n);
int ans = 0, cnt = 0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
if (a[i] != 0) {
ans = max(ans, cnt);
cnt = 0;
}
else
cnt++;
}
ans = max(ans, cnt);
cout << ans << endl;
}
return 0;
}
题意:有 n n n 本书,每本书可以使你学会 a a a 技能或 b b b 技能,或者同时学会 a , b a, b a,b技能。看每本书都有对应的代价,求学会两种技能的最小代价
思路:将书分为只学会 a a a技能和只学会 b b b技能和同时学会 a b ab ab技能,三种类型,用 3 3 3个变量维护三种类型各自的最小代价,最后得到答案。
signed main()
{
IO;
int t; cin >> t;
while (t--)
{
int n;cin >> n;
int cnt1 = oo, cnt2 = oo, cnt3 = oo;
for(int i = 1;i <= n;i ++)
{
int ti;cin >> ti;
string k;cin >> k;
if(k[0] == '1' && k[1] != '1')
cnt2 = min(cnt2, ti);
if(k[0] == '1' && k[1] == '1')
cnt1 = min(cnt1, ti);
if(k[0] != '1' && k[1] == '1')
cnt3 = min(cnt3, ti);
}
int ans = min(cnt1, cnt2 + cnt3);
if(ans >= oo)
cout << -1 << endl;
else
cout << ans << endl;
}
return 0;
}
题意:有一堆 n n n个金币,没次操作可以将其分为 a , b a,b a,b两堆,但是二者数量的比值必须为 2 : 1 2:1 2:1,问能否通过一系列操作得到个数为 m m m的堆
思路:
n ∗ ( 1 3 ) p ∗ ( 2 3 ) q = m n * (\frac{1}{3})^p * (\frac{2}{3})^q = m n∗(31)p∗(32)q=m
显然
m n = 2 q 3 p + q \frac{m}{n}=\frac{2 ^q}{3^{p+q}} nm=3p+q2q
所以通分 m / n m/n m/n,然后分解 m , n m,n m,n的因子,如果 m m m只包含因子 2 2 2, n n n只包含因子 3 3 3,且3的个数大于2的个数就有解
signed main()
{
IO;
int t; cin >> t;
while (t--)
{
int n, m;
cin >> n >> m;
int d = gcd(m, n);
int cnt2 = 0, cnt3 = 0;
m /= d, n /= d;
// cout << n << ' ' << m << endl;
while (m % 2 == 0)m /= 2, cnt2++;
while (n % 3 == 0)n /= 3, cnt3++;
if (m == 1 && m == n && cnt3 >= cnt2)
cout << "YES\n";
else
cout << "NO\n";
}
return 0;
}
纯bfs没什么其他的
#include
#define oo 0x3f3f3f3f
#define ll long long
#define OO 0x3f3f3f3f3f3f3f3f
#define IO ios::sync_with_stdio(false);cin.tie(nullptr)
#define endl "\n"
#define int ll
const int N = 2e5 + 10, M = 2 * N;
using namespace std;
typedef pair pii;
#define deb(i,x) if(int i==x) int k = 1;
#define all(x) x.begin(),x.end()
ll lowbit(ll x) { return x & -x; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll qmi(ll a, ll b, ll mod) {
ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; }
return res;
}
int g[1001][1001];
int vis[1001][1001];
int n, m;
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};
int bfs(int x, int y)
{
int ans = 0;
queue> q;
q.push({x, y}), vis[x][y] = 1;
while(q.size())
{
auto t = q.front(); q.pop();
int x = t[0], y = t[1];
ans += g[x][y];
for(int i = 0;i < 4;i ++)
{
int xx = x + dx[i], yy = y + dy[i];
if(xx > n || xx < 1 || yy > m || yy < 1)continue;
if(vis[xx][yy]) continue;
if(g[xx][yy] > 0)
{
vis[xx][yy] = 1;
q.push({xx, yy});
}
}
}
return ans;
}
signed main()
{
IO;
int t; cin >> t;
while (t--)
{
cin >> n >> m;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
cin >> g[i][j], vis[i][j] = 0;
int ans = 0;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
{
if(!vis[i][j] && g[i][j] > 0)
ans = max(ans, bfs(i, j));
}
cout << ans << endl;
}
return 0;
}
题意:有一个图,其根节点直接与 x x x个节点相邻,而这 x x x个节点每一个又都和 y y y个节点相邻。给定图中的点数和边数和所有边。求 x , y x,y x,y
思路:先求出图的最长直经,找到直径的两个端点,和直径长度。直径的中点就是根节点,它的度数就是 x x x,随便找个根节点直接相邻的节点 n o d e node node,其度数减一就是 y y y
#include
#define oo 0x3f3f3f3f
#define ll long long
#define OO 0x3f3f3f3f3f3f3f3f
#define IO ios::sync_with_stdio(false);cin.tie(nullptr)
#define endl "\n"
#define int ll
const int N = 2e5 + 10, M = 2 * N;
using namespace std;
typedef pair pii;
#define deb(i,x) if(int i==x) int k = 1;
#define all(x) x.begin(),x.end()
ll lowbit(ll x) { return x & -x; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll qmi(ll a, ll b, ll mod) {
ll res = 1; while (b) { if (b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; }
return res;
}
int n, m;
struct node
{
int v, ne;
}e[N];
int h[N] = { 0 }, tot = 0;
void add(int u, int v)
{
e[++tot] = { v, h[u] }; h[u] = tot;
}
int mx1 = 0, id1 = 1, id2;
void dfs(int u, int fa, int de)
{
if (de > mx1) mx1 = de, id1 = u;
for (int i = h[u]; i; i = e[i].ne)
{
int v = e[i].v;
if (v == fa)continue;
dfs(v, u, de + 1);
}
}
int k, to;
vector ans, tt;
void dfs1(int u, int fa)
{
if (u == id2) { ans = tt;}
tt.push_back(u);
for (int i = h[u]; i; i = e[i].ne)
{
int v = e[i].v;
if (v == fa)continue;
dfs1(v, u);
tt.pop_back();
}
}
signed main()
{
IO;
int t; cin >> t;
while (t--)
{
tt.clear();
tot = 0;
id1 = 1, id2 = 1;
mx1 = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++)h[i] = 0;
for (int i = 1; i <= m; i++)
{
int u, v; cin >> u >> v;
add(u, v), add(v, u);
}
dfs(1, 0, 0);
id2 = id1;
mx1 = 0;
dfs(id1, 0, 0);
int de = mx1 + 1;
k = de / 2 + 1;
dfs1(id1, 0);
to = ans[ans.size() / 2];
int x = 0;
for (int i = h[to]; i; i = e[i].ne)x++;
int y = 0;
for (int i = h[e[h[to]].v]; i; i = e[i].ne) y++;
cout << x << ' ' << y - 1 << endl;
}
return 0;
}
题意:有一个塔状结构如图
对于输入的 n n n,求出直接或间接位于 n n n上方所有部分的和,每部分都是形如 i 2 i^2 i2的值。
思路:记忆化+容斥
对于输入的 n n n,可以用二分求出它所在的层数的上一层是第几层,令其为 k k k。
然后就可以分3种情况得到直接位于它上方的部分的值。
位于当前层的第一个,直接在其上方的部分就一个,值为 k ∗ ( k + 1 ) / 2 − k + 1 k*(k + 1)/2-k+1 k∗(k+1)/2−k+1
位于当前层最后一个,和第一种类似,其值为 k ∗ ( k + 1 ) k*(k +1 ) k∗(k+1)/2
位于当前层第 d d d个KaTeX parse error: Undefined control sequence: \and at position 9: d \ne 1 \̲a̲n̲d̲ ̲d\ne最后一个,直接在其上方的有两个。分别为 k ∗ ( k + 1 ) / 2 − k + d k*(k+1)/2-k+d k∗(k+1)/2−k+d 和 k ∗ ( k + 1 ) / 2 − k + d − 1 k*(k+1)/2-k+d-1 k∗(k+1)/2−k+d−1
int vis[N] = { 0 };
int get(int n)
{
int l = 1, r = 1e4;
while (l < r)
{
int mid = (l + r + 1) >> 1;
if ((mid + 1) * mid / 2 <= n) l = mid;
else r = mid - 1;
}
if (l * (l + 1) / 2 == n) l--;
return l;
}
int res[N] = { 0 };
int dfs(int n)
{
if (res[n])return res[n];
int ans = 0;
int m = n;
int k = get(m);
int num = k * (k + 1) / 2;
int d = m - num;
ans += m * m;
int cnt = 0;
if (d != k + 1)
{
cnt++;
int dd = dfs(num - k + d);
ans += dd;
}
if (d != 1)
{
cnt++;
int dd = dfs(num - k - 1 + d);
ans += dd;
}
if (cnt == 2) {
int up = num - k + d - 1;
int floor = get(up);
num = floor * (floor + 1) / 2;
d = up - num;
int dd = dfs(num - floor + d);
ans -= dd;
}
return res[m] = ans;
}
signed main()
{
IO;
int t; cin >> t;
while (t--)
{
int n; cin >> n;
for (int i = 1; i <= n; i++)vis[i] = 0;
vis[n] = 1;
int ans = dfs(n);
res[n] = ans;
cout << ans << endl;
}
return 0;
}
DP
signed main()
{
IO;
const int mod = 1e9 + 7;
int t; cin >> t;
while (t--)
{
int n, k; cin >> n >> k;
vector a(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
vector dp(n + 1, vector(100));
int ans = 0;
for(int i = 1; i <= n; i++) {
dp[i][a[i]] = 1;
for(int j = 0; j <= 64; j++) {
dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;
dp[i][j & a[i]] = (dp[i][j & a[i]] + dp[i - 1][j]) % mod;
}
}
for(int i = 0;i < 64;i ++){
int d = 0;
for(int j = 0;j <= 5;j ++)
if(i & (1 << j)) d ++;
if(d == k)ans = (ans + dp[n][i]) % mod;
}
cout << ans % mod << endl;
}
return 0;
}