A Lucky?(模拟)
点此进入题面
题意:
思路:
模拟
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e5 + 10;
int n, a[N];
signed main()
{
int t; cin>>t;
while(t--)
{
string s; cin>>s;
string s1 = s.substr(0, 3), s2 = s.substr(3);
if((s1[0] - '0') + s1[1] - '0'+ s1[2] - '0' == (s2[0] - '0') + (s2[1] - '0') + (s2[2] - '0')) puts("YES");
else puts("NO");
}
return 0;
}
B Equal Candies(贪心)
点此进入题面
题意:
思路:
贪心
最后每个盒子里糖的数量一定是 min(ai)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e2 + 10;
int n, a[N];
signed main()
{
int t; cin>>t;
while(t--)
{
cin>>n;
int mn = 0x3f3f3f3f;
for(int i=1; i<=n; ++i) cin>>a[i], mn = min(mn, a[i]);
int sum = 0;
for(int i=1; i<=n; ++i)
{
if(a[i]==mn) continue;
sum += a[i] - mn;
}
cout<<sum<<'\n';
}
return 0;
}
C Most Similar Words(暴力)
点此进入题面
题意:
思路:
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e5 + 10;
int n, a[N];
string s[100];
int cal(string a, string b)
{
int step = 0;
for(int i=0; i<a.size(); ++i)
{
int t = abs(a[i] - b[i]);
step += t;
}
return step;
}
signed main()
{
int t; cin>>t;
while(t--)
{
int m; cin>>n>>m;
for(int i=1; i<=n; ++i)
{
cin>>s[i];
}
int mn = 0x3f3f3f3f;
for(int i=1; i<=n-1; ++i)
{
for(int j=i+1; j<=n; ++j)
{
int tmp = cal(s[i], s[j]);
mn = min(mn, tmp);
}
}
cout<<mn<<'\n';
}
return 0;
}
D X-Sum(模拟)
点此进入题面
题意:
思路:
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e5 + 10;
int n, m, a[N];
int g[300][300];
bool st[300][300];
int dx[] = {-1, -1, 1, 1}, dy[] = {1, -1, 1, -1};
bool jud(int x, int y)
{
if(x<1 || x>n || y<1 || y>m) return true;
return false;
}
int cal(int x, int y)
{
int sum = 0;
st[x][y] = true, sum += g[x][y];
for(int i=0; i<4; ++i)
{
int a = x, b = y;
while(1)
{
a += dx[i], b += dy[i];
if(jud(a, b)) break;
sum += g[a][b];
st[a][b] = true;
}
}
return sum;
}
signed main()
{
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];
}
}
int ans = -1;
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=m; ++j)
{
ans = max(ans, cal(i, j));
}
}
cout<<ans<<'\n';
}
return 0;
}
E Eating Queries(前缀和 + 贪心 + 二分)
点此进入题面
题意:
思路:
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1.5e5 + 10;
int n, q, a[N], s[N];
signed main()
{
int t; cin>>t;
while(t--)
{
cin>>n>>q;
for(int i=1; i<=n; ++i)
{
scanf("%lld", &a[i]);
}
sort(a+1, a+n+1, greater<int>());
for(int i=1; i<=n; ++i)
{
s[i] = s[i-1] + a[i];
}
while(q--)
{
int tgt;
scanf("%lld", &tgt);
int t = lower_bound(s+1, s+n+1, tgt) - s;
if(t==n+1) puts("-1");
else printf("%lld\n", t);
}
}
return 0;
}
F Longest Strike(双指针)
点此进入题面
题意:
思路:
本题我们使用 map
,map
在哈希的时候会 按值的大小自动进行从小到大排序 即可以省去 sort
如果用 unordered_map
则应该先对 v
数组排序,
但是这样子做会喜提一发TLE
// two pointers
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef map<int, int> mi;
typedef unordered_map<int, int> umi;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 2e5 + 10;
int a[N], n;
signed main()
{
int t; cin>>t;
//t = 1;
while(t--)
{
int n, k; scanf("%d%d", &n, &k);
mi hah;
for (int i=1; i<=n; ++i)
{
scanf("%d", &a[i]);
hah[a[i]] ++;
}
vi v;
for(auto it : hah) if (it.y >= k) v.pb(it.x);
if(!v.size()) { puts("-1"); continue; }
int ans = -1, l = 0, r = 0;
int i, j;
for(i=0, j=0; i<v.size(); ++i)
{
if(v[i] - v[j]==i - j) continue;
else
{
if(ans < v[i-1]-v[j])
{
l = v[j], r = v[i-1];
ans = v[i-1] - v[j];
}
j = i;
}
}
if(ans < v[i-1] - v[j]) l = v[j], r = v[i-1];
cout<<l<<' '<<r<<'\n';
}
return 0;
}
G White-Black Balanced Subtrees(树形 dp)
点此进入题面
题意:
思路:
状态表示:
dp[i][0]
:以 i
号节点为根节点 所代表子树的 白色节点 个数。
dp[i][1]
:以 i
号节点为根节点 所代表子树的 黑色节点 个数。
状态计算:
dp[i][0] = dp[s1][0] + dp[s2][0] + ... + dp[si][0]
(s1 s2 ... si
代表 节点 u
的所有子树)
dp[i][1] = dp[s1][1] + dp[s2][1] + ... + dp[si][1]
(s1 s2 ... si
代表 节点 u
的所有子树)
问题答案:
节点 u ∈ 1 ~ n
中 满足 dp[u][0]==dp[u][1]
的 节点个数 count
//dp[u][0]: u th subtree's white node counts
//dp[u][1]: u th subtree's black node counts
//if(dp[u][0]==dp[u][1]) (u = 1 2 ... n) update the answer++
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 4e3 + 10;
int a[N], n;
int p[N], dp[N][2];
string col;
vi g[N];
void clear()
{
memset(dp, 0, sizeof dp);
col.clear();
for(int i=1; i<=n; ++i) g[i].clear();
}
void dfs(int u, int father)
{
if(col[u]=='W') dp[u][0] = 1;
else dp[u][1] = 1;
for(auto v : g[u])
{
if(v==father) continue;
dfs(v, u);
dp[u][0] += dp[v][0], dp[u][1] += dp[v][1];
}
}
signed main()
{
int t; cin>>t;
//t = 1;
while(t--)
{
cin>>n; clear();
for(int i=2; i<=n; ++i)
{
cin>>p[i];
g[i].pb(p[i]), g[p[i]].pb(i);
}
cin>>col;
col = " " + col;
dfs(1, -1);
int cnt = 0;
for(int i=1; i<=n; ++i) if(dp[i][0]==dp[i][1]) ++cnt;
cout<<cnt<<'\n';
}
return 0;
}
H1 Maximum Crossings (Easy Version)(暴力求解逆序对)
点此进入题面
题意:
思路:
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e3 + 10;
int a[N], n;
signed main()
{
int t; cin>>t;
//t = 1;
while(t--)
{
cin>>n;
for(int i=1; i<=n; ++i) cin>>a[i];
int res = 0;
for(int i=1; i<n; ++i)
{
for(int j=i+1; j<=n; ++j)
{
if(a[i] >= a[j]) ++res;
}
}
cout<<res<<'\n';
}
return 0;
}
H2 Maximum Crossings (Hard Version)(树状数组求解逆序对)
点此进入题面
题意:
思路:
与上题一致,但是根据题目给出的 数据范围,我们要将时间复杂度控制在 O(nlogn)
以内,这里我们考虑用 树状数组 来做。
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 2e5 + 10;
int a[N], n;
int tr[N];
int lowbit(int x) { return x & (-x); }
void add(int x, int v)
{
for(; x<=n; x+=lowbit(x)) tr[x] += v;
}
int ask(int x)
{
int res = 0;
for (int i=x; i>0; i -= lowbit(i)) res += tr[i];
return res;
}
void clear()
{
memset(tr, 0, sizeof tr);
memset(a, 0, sizeof a);
}
signed main()
{
int t; cin>>t;
//t = 1;
while(t--)
{
cin>>n; clear();
for(int i=1; i<=n; ++i) scanf("%lld", &a[i]);
int res = 0;
for(int i=n; i>=1; --i)
{
res += ask(a[i]);
add(a[i], 1);
}
cout<<res<<'\n';
}
return 0;
}