A. Treasure Chest
扛着箱子能拿多远,拿多远
#include
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
void solve()
{
int x, y, k;
cin >> x >> y >> k;
if (y <= x)
{
cout << x << endl;
return;
}
else
{
if (k >= (y - x))
{
cout << y << endl;
}
else
{
cout << y + (y - (x + k)) << endl;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
B. Points and Minimum Distance
排序后,相邻两个数,分别作为两个坐标的相同坐标值是最小的
#include
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
void solve()
{
int n;
cin >> n;
vector a(2 * n);
for (int i = 0; i < 2 * n; i++)
{
cin >> a[i];
}
sort(a.begin(), a.end());
int sum = 0;
for (int i = 1; i < n; i++)
{
sum += ((a[i] - a[i - 1]) + (a[i + n] - a[i + n - 1]));
}
cout << sum << endl;
for (int i = 0; i < n; i++)
{
cout << a[i] << " " << a[i + n] << "\n";
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
C. Torn Lucky Ticket
赛时想着能不能冲过去,写了个时间复杂度O(n^3/2 ) ~O(n^2)的解法,直接timed out
#include
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
const int N = 2e5 + 5;
int dp[N][6]; // dp[i][j]表示第i个字符串前j个数之和
int num[N]; // id[i]表示第i个字符串的长度
void solve()
{
int n;
cin >> n;
vector ji, ou;
ll ans = 0;
for (int i = 1; i <= n; i++)
{
string a;
cin >> a;
for (int j = 0; j < a.length(); j++)
{
dp[i][j + 1] = dp[i][j] + a[j] - '0';
}
num[i] = a.length();
if (a.length() % 2 == 0)
{
ou.push_back(i);
}
else
{
ji.push_back(i);
}
}
for (int i = 1; i <= n; i++)
{
if (num[i] % 2 == 1)
{
for (auto k : ji)
{
if (k == i)
{
ans++;
}
else
{
int avnum = (num[i] + num[k]) / 2;
if (num[i] == num[k])
{
if (dp[i][num[i]] == dp[k][num[k]])
{
ans++;
}
}
else if (num[i] < num[k])
{
if (dp[i][num[i]] + dp[k][avnum - num[i]] == dp[k][num[k]] - dp[k][avnum - num[i]])
{
ans++;
}
}
else
{
if (dp[i][avnum] == dp[k][num[k]] + dp[i][num[i]] - dp[i][avnum])
{
ans++;
}
}
}
}
}
else
{
for (auto k : ou)
{
if (k == i)
{
ans++;
}
else
{
int avnum = (num[i] + num[k]) / 2;
if (num[i] == num[k])
{
if (dp[i][num[i]] == dp[k][num[k]])
{
ans++;
}
}
else if (num[i] < num[k])
{
if (dp[i][num[i]] + dp[k][avnum - num[i]] == dp[k][num[k]] - dp[k][avnum - num[i]])
{
ans++;
}
}
else
{
if (dp[i][avnum] == dp[k][num[k]] + dp[i][num[i]] - dp[i][avnum])
{
ans++;
}
}
}
}
}
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
// cin >> t;
t = 1;
while (t--)
{
solve();
}
return 0;
}
最后写了个map嵌套map的,再想想有没有更优解吧:
#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll ans;
map > mp;
void fun(string s){
ans++;
int sum=0;
ll lq,lh,sq=0,sh;
for(int i=0;ilh){
ans+=(mp[lq-lh][sq-sh]);
}else if(lq vs;
bool cmp(string s1,string s2){
return s1.length()>n;
string s;
ans=0;
for(int i=0;i>s;
vs.push_back(s);
}
sort(vs.begin(),vs.end(),cmp);
for(int i=0;i> T;
while (T--) {
solve();
}
return 0;
}
D. XOR Construction
/*
给a数组做一个异或前缀和得到
a[0]^a[1],a[0]^a[2],a[0]^a[3]....a[0]^a[n-2]
相当于给a[1~n-1]都异或上了一个a[0]
那么根据题目要求,0~n-1必须在数组b中出现且仅一次
那么按照原来的正常情况下,对于二进制上的每一位,[0,n-1]中这一位应该有多少个1
由于:每个i都有b[i]^b[i+1]=a[i],那么就有b[i+1]=a[i]^b[i],递推式变化为:b[i+1]=a[i+1]^a[i]^..^a[0]^b[0],即为前缀a[i+1]^b[0]
讨论分析就可以知道b[0]在二进制表示下这一位是不是1,求出后再异或一下就是了
*/
#include
using namespace std;
typedef long long ll;
#define has1 __builtin_popcount
void solve()
{
int n;
cin >> n;
vector a(n - 1);
for (int i = 0; i < n - 1; i++)
cin >> a[i];
for (int i = 1; i < n - 1; i++)
a[i] ^= a[i - 1];
int x = 0;
for (int i = 0; i < 20; i++)
{ // 枚举第几位
int cnt[2]{}, target[2]{};
for (int j = 0; j < n; j++) // 这一位应该有多少个1
{
target[j >> i & 1] += 1;
}
for (int j = 0; j < n - 1; j++) // 现在有多少个1
{
cnt[a[j] >> i & 1] += 1;
}
if (cnt[1] != target[1])
{
x |= 1 << i;
}
}
cout << x << ' ';
for (int i = 0; i < n - 1; i++)
cout << (a[i] ^ x) << ' ';
cout << '\n';
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
// cin >> t;
t = 1;
while (t--)
{
solve();
}
return 0;
}