A題
思路
重點在於題目操作蘊含的奇偶數關係,一個偶數可以和一個奇數一起刪除,兩個奇數可以一起刪除。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
vector<int>ar(n);
int j=0,o=0;//j代表奇數的個數,o代表偶數的個數
for(int i=0;i<n;i++){
cin>>ar[i];
if(ar[i]&1){
j++;
}else{
o++;
}
}
if(o>j)cout<<max(0,o-j);
else{
if((j-o)&1){
cout<<1;
}else{
cout<<0;
}
}
}
B題
思路
只需把遞迴式子拆開來,等差數列求個和,每步操作%P防止超出精度就行。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
#define int long long
int t;
cin>>t;
int p = 998244353;
while(t--){
int a,x;
cin >> a >> x;
if(x==1){
cout<<a%p<<'\n';
continue;
}
cout<<(x*(x-1)/2)%p*a%p*a%p<<'\n';
}
}
C題
思路
排序貪心即可,找在x範圍內最大的ai,和它前面共有幾個數。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
vector<int>a(n);
for(auto &x:a){
cin>>x;
}
sort(a.begin(),a.end());
int cnt=0;
int maxn=0;
for(auto x:a){
if(x<=m){
cnt++;
maxn=x;
}
}
cout<<cnt<<" "<<m-maxn<<'\n';
}
D題
思路
BFS模板題,dxdy裡存四個方向,寬度優先搜尋,每一個向外擴充套件,最先搜到的就是最少的步數。
程式碼
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n, m;
char g[N][N];
int d[N][N];
int bfs()
{
queue<PII> q;
memset(d, -1, sizeof d);
d[0][0] = 0;
q.push({0, 0});
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
while (q.size())
{
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i ++ )
{
int x = t.first + dx[i], y = t.second + dy[i];
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] !=g[t.first][t.second] && d[x][y] == -1)
{
d[x][y] = d[t.first][t.second] + 1;
q.push({x, y});
}
}
}
return d[n - 1][m - 1];
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
cin >> g[i][j];
cout << bfs() << endl;
return 0;
}
E題
思路
上一題的構造方法有很多,重點在於構造出一條滿足條件的路徑,且把其他路堵住,程式碼很shit。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
char g[n+1][m+1];
int cnt=0;
bool flag=false;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==n){
g[i][j]='a'+cnt;
if(j%2!=0)cnt++;
}
else {
g[i][j]='a'+cnt;
if(j%2==0)cnt++;
}
if(cnt==26)cnt=0;
}
if(cnt==26)cnt=0;
}
if(g[n-1][2]==g[n][2]){
int p=g[n-1][2]-'a';
p++;
if(p==26)p=0;
g[n][3]='a'+p;
p++;
if(p==26)p=0;
g[n-1][3]='a'+p;
p++;
for(int i=4;i<=m;i++){
g[n-1][i]='a'+p;
p++;
if(p==26)p=0;
}
g[n][m]='a'+p;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<g[i][j];
}
cout<<'\n';
}
}
F題
思路
簽到,只要看每個後面是否有大寫,有大寫代表這裡需要一次操作,答案++。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string ss;
cin>>ss;
int cnt=0;
for(int i=0;i<ss.size()-1;i++){
if(ss[i+1]<='Z'&&ss[i+1]>='A'){
cnt++;
i++;
}
}
cout<<cnt<<"\n";
}
G題
思路
依舊是排序貪心,只要剩餘數量大於k個就取就行。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
#define int long long
int n,k;
cin>>n>>k;
vector<int>ar(n+1);
int sm=0;
for(int i=1;i<=n;i++){
cin>>ar[i];
sm+=ar[i];
}
sort(ar.begin()+1,ar.end());
int sum=0;
int cnt=0;
if(sm%k==0){
cout<<0;
return 0;
}
for(int i=n;i>0;i--){
sum+=ar[i];
cnt++;
if(sum>sm-sm/k*k){
break;
}
}
cout<<cnt;
}
H題
思路
利用set判斷是否這位數出現過,把各個特殊情況判一下,是否是一個排列,否的話,n大於1,就把第二位的值改成第一位,n==1時,就把第一位的值改成2。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
vector<int>ar(n);
set<int>st;
bool flag=true;
for(int i=0;i<n;i++){
int xp;
cin>>xp;
if(xp>n)flag=false;
if(st.count(xp)){
flag=false;
}
else st.insert(xp);
ar[i]=xp;
}
if(!flag)cout<<0<<'\n';
else if(n!=1){
cout<<1<<'\n'<<2<<' '<<ar[0]<<'\n';
}
else cout<<1<<'\n'<<1<<' '<<2;
}