?題目意思:
判斷字符串是否可以按照題目條件縮短。
思路:
用棧的思想寫,對每一次的大小寫都進行滾動判斷。
tips:
這里面要注意的東西就有一點多了,首先是字符串的遍歷問題auto更方便,其次是對小寫和大寫字母的判斷,可以說字符串大部分的細節這道題目都有涉及。
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){int n;cin>>n;string ac;cin>>ac;stack<char>p;for(auto it:ac){if(!p.empty()){//這里是判斷是否為空,但是容易寫成whilechar top=p.top();//找出頂端的字母if(it>top&&islower(top)&& islower(it)&&(it-'a'+1+top-'a'+1==27)){//小寫的情況下,兩者都要是小寫的,而且滿足一定的條件,后大于前且兩者相加為27p.pop();continue;}if(it<top&&isupper(top)&&isupper(it)&&(it-'A'+1+top-'A'+1==27)){//大寫的情況下,兩者都要是大寫的,而且滿足一定的條件,前大于后且兩者相加為27p.pop();continue;}}p.push(it);}cout<<p.size()<<endl;
}
signed main(){int n=1;while(n--){solve();}
}
題目意思:
給定一些數字,判斷這些數字是否能用其他平方數字通過迭代的方式得到。
思路:
平方數字有4,9,16,25....但是我們這里只需要取4,9即可,因為大于9的平方數字我們都可以通過較小的平方數字得到。故有意義的平方數字只有4,9。
拿4舉例子
1,4,7,...3k+1
拿9舉例子
1,9,17,...8k+1
拿25舉例子
1,24,47,...23k+1
之后由于題目中可以反復取相同或者不相同的平方數字進行若干次操作,我們可以對上述數字進行通解寫法,3a+1+23b+8c+...(其他平方數字),但是我們要找到這一串通解表達最小的數字是多少。
麥樂雞定理??
我們可以根據上數定理找到最小可表達的數字,這里我們用3a+8b+1得到14。
故大于14的數字該表達式都可以表達。
我們只需要在14內部進行特判即可。(手動模擬一下)
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){int x;cin>>x;if(x==2||x==3||x==5||x==6||x==8||x==11||x==14){cout<<"No"<<endl;}else{cout<<"Yes"<<endl;}
}
signed main(){int n=1;cin>>n;while(n--){solve();}
}
題目意思:
給定一個數組和若干次給每個數字加一的操作下,找到長度為m的字串且奇偶交替的最小次數。
思路:滑動窗口想法,對于每一個長度為m的字串進行判斷找最小,從頭到尾遍歷一遍。
奇偶交替的情況可以是奇偶奇偶奇偶也可以是偶奇偶奇偶奇,說到底是數組下標和數字之間的關系。故我們可以將奇數標記為1,偶數標記為0,進行狀壓轉移。
最后按照兩種情況分別求個前綴和(如果數字的奇偶性和當下交替情況不符合,我們就直接操作加1)
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve() {int n, m;cin >> n >> m;vector<int> a(n);for (int i = 0; i < n; i++) {cin >> a[i]; // 輸入數組a}// 定義兩個數組aa和bb,分別表示將a[i]調整為以奇數開頭和偶數開頭的奇偶交替序列所需的操作次數vector<int> aa(n), bb(n);for (int i = 0; i < n; i++) {// aa[i]: 如果a[i]的奇偶性與i的奇偶性不一致,則需要調整(操作次數為1),否則為0aa[i] = (a[i] % 2 != i % 2) ? 1 : 0;// bb[i]: 如果a[i]的奇偶性與i的奇偶性相反(即i是偶數時a[i]是奇數,i是奇數時a[i]是偶數),則需要調整(操作次數為1),否則為0bb[i] = (a[i] % 2 != !(i % 2)) ? 1 : 0;}// 前綴和數組,用于快速計算區間和vector<int> qian(n + 1, 0), hou(n + 1, 0);for (int i = 0; i < n; i++) {qian[i + 1] = qian[i] + aa[i]; // qian[i+1]表示前i個元素中aa的和hou[i + 1] = hou[i] + bb[i]; // hou[i+1]表示前i個元素中bb的和}int answer = 8e18; // 初始化為一個很大的數,表示無窮大// 滑動窗口,遍歷所有長度為m的子數組for (int i = 0; i + m <= n; i++) {// 計算當前窗口內aa的和(即調整為以奇數開頭的奇偶交替序列的操作次數)int sum = qian[i + m] - qian[i];// 計算當前窗口內bb的和(即調整為以偶數開頭的奇偶交替序列的操作次數)int cnt = hou[i + m] - hou[i];// 更新最小操作次數answer = min({answer, sum, cnt});}cout << answer << endl;
}signed main() {int t = 1;while (t--) {solve();}return 0;
}