第一题就是车走行和列,除了它自己当前在的位置外,将相同行和列的对应字符都直接输出即可
#include
using namespace std;
int main()
{
int T;
cin >> T;
while(T --)
{
string s;
cin >> s;
int a = (int)(s[1] - '0');
for(int i = 1; i <= 8 ; i ++)
if(i != a)
cout << s[0] << i << endl;
for(int i = 0 ;i < 8 ; i ++)
if((char)(i + 'a') != s[0])
cout << (char)(i + 'a') << (int)(s[1] - '0') << endl;
}
return 0;
}
第二题是要根据输入字符串中大写B和小写b的个数,删除对应最右边的大写字母或小写字母,其中B和b不计入最终的输出字符串中,最后输出得到的字符串。这当时想了很久,后面突然发现可以开两个vector
#include
#include
#include
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while(T --)
{
string s;
cin >> s;
int cnt = 0;
vector<pair<int, char>> a, b;
for(auto c : s)
{
if(c >= 'A' && c <= 'Z')
{
if(c == 'B' && a.size()) a.pop_back();
else if(c != 'B') a.push_back({++cnt, c});
}
else if(c >= 'a' && c <= 'z')
{
if(c == 'b' && b.size()) b.pop_back();
else if(c != 'b') b.push_back({++cnt, c});
}
}
// for(int i = 0 ;i < a.size() ;i ++)
// cout << a[i].first << " " << a[i].second << " ";
// // else if(b[i].first == i)
// // cout << b[i].second;
// puts("");
// for(int i = 0 ;i < b.size() ;i ++)
// cout << b[i].first << " " << b[i].second << " ";
// puts("");
sort(a.begin(), a.end());
sort(b.begin(), b.end());
int i = 0, j = 0, la = a.size(), lb = b.size();
while(i < la && j < lb)
{
if(a[i].first < b[j].first && i < la)
{
cout << a[i ++].second;
// cout << " " << a[i].second << " ";
}
else if(j < lb && a[i].first > b[j].first)
{
cout << b[j ++].second;
// cout << " " << b[j].first << " ";
}
}
while(i < la) cout << a[i++].second;
while(j < lb) cout << b[j++].second;
cout << endl;
}
return 0;
}
这题根据贪心策略分析可知,无论字符串的形式如何变化,最终结果定是0或1中的一个,我们可以先求出该字符串中每个字符的出现次数,找到最大的那个cnt,要是cnt * 2 >= n说明该字符串最多最多就只能用剩下的其他字符消去,即res = cnt - (n - cnt);反之,若cnt * 2 <= n的话,最多能直接将次数为cnt的字符全部消去,此时我们只用看当前字符串的长度就行,即res = n % 2 。
#include
#include
#include
using namespace std;
int n, t;
int main()
{
cin >> t;
while(t --)
{
cin >> n;
string s;
cin >> s;
int a[27];
memset(a, 0, sizeof a);
int res = 0;
for(auto x : s){
a[x - 'a'] ++;
res = max(res, a[x - 'a']);
}
if(res * 2 >= n)
{
cout << res - (n - res) << endl;
}
else
cout << n % 2 << endl;
}
return 0;
}
这题求的是每次Jump的最小距离,它涉及到区间问题,可以每次二分它的最小距离mid,要是满足条件,则二分左边,反之二分右边。
对于每一个mid,我们可以对它做一次遍历,开两个变量,一个往左边跳,一个往右边跳,要是有一个不符合,直接返回0;反之,遍历完返回1。如下图所示:
#include
#include
#include
using namespace std;
int n, t;
pair<int, int> v[200010];
bool check(int mid)
{
int l = 0, r = 0;
for(int i = 0 ; i < n ;i ++)
{
l -= mid, r += mid;
if(l > v[i].second || r < v[i].first) return 0;
l = max(l, v[i].first), r = min(r, v[i].second);
}
return 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> t;
while(t --)
{
cin >> n;
for(int i = 0 ;i < n ;i ++)
{
cin >> v[i].first >> v[i].second;
}
int l = 0, r = 1000000001;
while(l < r)
{
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
cout << r << endl;
}
return 0;
}
#include
#include
#define int long long
using namespace std;
int n, t;
int val[10];
void init() //预处理每一种情况的所有可能组合
{
for(int i = 0 ; i < 10 ; i ++)
for(int j = 0 ;j < 10 ;j ++)
for(int k = 0 ;k < 10 ; k ++)
if(i + j + k < 10)
val[i + j + k] ++;
}
signed main()
{
init();
cin >> t;
while(t --)
{
cin >> n;
int res = 1;
while(n) //既然我们能用每一位的组合拼成这个数,那肯定能对应一种合法的情况使a + b + c == n
{
res *= val[n % 10];
n /= 10;
}
cout << res << endl;
}
return 0;
}