思路:模拟计算器
LL a;
char op;
cin >> a >> op;
if(op == '+'){
cout << 1 <<" " << a -1 <<endl;
}
else if (op == '-'){
cout << a + 1 <<" " << 1 << endl;
}
else{// (op == '*')/
cout << a << " " << 1 << endl;
}
思路:我们注意到如果n - k < t,即拉不开一个区间,那么答案是0,其次的最优解为每k天讲一次,模拟即可
int t_;
cin >> t_;
while(t_--){
LL n, t, k;
cin >> n >> t >> k;
if (n - k < t) {
cout << "0\n";
} else {
cout << min((n - k) / t, k + 1) << endl;
}
}
我们注意到1 ^ 1 = 0 1 ^ 0 = 1 0 ^ 1 = 1 0 ^ 0 = 0,所以反置任意一位就可以改变c的答案
我们发现 ai ^ bi != ci的时候只有两种状况
1:ai ^ bi = 1 ci = 0
2:ai ^ bi = 0 ci = 1
首先能够发现每次换位可以修改两个数,而反置只能修改一个数,所以很明显,如果2 * value_1 <= value_2,那么反置的收益大于互换,反之反置小于互换
我们注意到每次换位的最优操作是修改两位1 0使得他们正好1 0 互换,所以我们可以通过遍历每一位,计算 a[i] ⊕ b[i]
是否等于 c[i]
。如果不等,说明这一位需要操作。记录这些不匹配的情况在 cnt
数组中,并计算总的不匹配位数 s
。
具体的模拟方式,可以记录一下几个1 和 0 的分配,然后和操作次数做比较,然后模拟即可
int n; LL x, y;
cin >> n >> x >> y;
y = min(y, 2 * x);
string a, b, c;
cin >> a >> b >> c;
int sum = 0;
for(int i = 0; i < n; i++){
int b1 = a[i] - '0';
int b2 = b[i] - '0';
int b3 = c[i] - '0';
if ((b1 ^ b2) != b3){
cnt[b1][b2] += 1;
sum += 1;
}
}
int max_val = 0;
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
max_val = max(max_val, cnt[i][j]);
}
}
int match = sum / 2;
if (max_val * 2 > sum) match = sum - max_val;
cout << match * y + (sum - 2 * match) * x << endl;
一道超级大模拟题
注意到三子连线,只需要任意组合成XXX即可,本质是模拟,把各个XXX的情况模拟出来即可
vector<string>s(3);
for(int i = 0;i<3;i++){
cin>>s[i];
}
vector<int>a(3,0);
vector<int>b(3,0);
for(int i = 0;i<3;i++){
for(int j = 0;j<3;j++){
if(s[i][j]=='G'){
a[i]++;
}
}
}
for(int i = 0;i<3;i++){
for(int j = 0;j<3;j++){
if(s[j][i]=='G'){
b[i]++;
}
}
}
bool f = false;
for(int i = 0;i<3;i++){
if(s[i]=="GGX"||s[i]=="XGG"||s[i]=="GXG"||s[i]=="XXG"||s[i]=="XGX"||s[i]=="GXX"||s[i]=="XXX"){
f = true;
}
}
for(int j = 0;j<3;j++){
string str;
for(int i = 0;i<3;i++){
str.push_back(s[i][j]);
}
if(str=="GGX"||str=="XGG"||str=="GXG"||str=="XXG"||str=="XGX"||str=="GXX"||str=="XXX"){
f = true;
}
}
string s1;
string s2;
s1.push_back(s[0][0]);
s1.push_back(s[1][1]);
s1.push_back(s[2][2]);
s2.push_back(s[0][2]);
s2.push_back(s[1][1]);
s2.push_back(s[2][0]);
if(s1=="GGX"||s1=="XGG"||s1=="GXG"||s1=="XXG"||s1=="XGX"||s1=="GXX"||s1=="XXX"){
f = true;
}if(s2=="GGX"||s2=="XGG"||s2=="GXG"||s2=="XXG"||s2=="XGX"||s2=="GXX"||s2=="XXX"){
f = true;
}
if(f){
cout<<"Yes"<<endl;
}else{
bool op =false;
for(int i = 0;i<3;i++){
for(int j = 0;j<3;j++){
if(a[i]+b[j]==6){
op = true;
break;
}
}
}
if(op==true){
cout<<"Yes"<<endl;
}else{
cout<<"No"<<endl;
}
}
思路:手动演算一下能够发现所有情况都能够构造出来,除了 0 num和num 0 的情况
模拟即可
LL n , m;
cin >> n >> m;
if(n == 0 && m == 0){
cout <<"Yes\n";
}
else{
if(n == 0 || m == 0){
cout <<"No\n";
}
else{
cout <<"Yes\n";
}
}
思路:高中的时候学过,路程是时间和速度围成的关于x轴的面积,每一秒更新一下速度然后模拟即可,要注意速度 < 0 的情况
int n;cin >> n;
string s;cin >> s;
int v = 0;
int q = 0;
for(auto i : s){
if(i == '0'){
v+= 10;
q += v;
}
else if(i == '1'){
v -= 5;
v = max(v , 0LL);
q += v;
}
else{
v -= 10;
if(v > 0){
q += v;
}
v += 10;
}
}
cout << q << endl;