A
很顯然兩種相同的數字要平分到兩個組裏面去, 即這個數字的總數要是偶數
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <utility>
using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 1e5 + 10;
int n, m;
int a[10], b[10];
int main(){
scanf("%d", &n);
int x;
for(int i = 0; i < n; ++i){
scanf("%d", &x);
a[x]++;
}
for(int i = 0; i < n; ++i){
scanf("%d", &x);
b[x]++;
}
bool flag = true;
int sum = 0;
for(int i = 1; i <= 5; ++i){
if((a[i] + b[i]) % 2 == 1){
flag = false;
break;
}
sum += abs(a[i] - b[i]) / 2;
}
if(!flag) puts("-1");
else if(sum % 2 == 1) puts("-1");
else printf("%d\n", sum / 2);
return 0;
}
B
這題的話剛開始確實不知道怎麼去做
後來看看n的大小, hhh不知道怎麼想到n的長度了, 直接二進制枚舉剩下的數字, 然後判斷就行了
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <utility>
using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 1e5 + 10;
int n, m, k;
char st[105];
int num[qq];
int main(){
scanf("%s%d", st, &k);
ll mod = 1;
for(int i = 1; i <= k; ++i)
mod *= 10ll;
int n = strlen(st);
int minx = 15;
for(int i = 0; i < (1 << n); ++i){
ll sum = 0;
int cnt = 0;
for(int j = 0; j < n; ++j)
if(i & (1 << j)) sum = sum * 10 + st[j] - '0', cnt++;
if(sum % mod == 0){
int digit = 0;
if(sum == 0) digit = 1;
else{
while(sum){
sum /= 10;
digit++;
}
}
int p = cnt - digit;
minx = min(minx, n - cnt + p);
}
}
printf("%d\n", minx);
return 0;
}
稍微注意一下全部選出的是0的情況
C
這題也挺簡單的, 就是說n個物品現在價格是ai, 一周後價格是bi, 你要買下這n個物品, 但是現在就必須買至少k個, 很顯然如果一個物品一周之後價格邊高了, 那麼肯定現在就要把它買下來, 也就是按b[i] - a[i] 排一個序, 先選k個, 如果後面的物品還是漲價就繼續買, 一直買到它沒有或者買到的物品降價爲止
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <utility>
using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 2e5 + 10;
int n, m, k;
struct Item{
int a, b;
bool operator < (const Item &it)const{
return b - a > it.b - it.a;
}
}item[qq];
int main(){
scanf("%d%d", &n, &k);
int cnt = 0;
for(int i = 0; i < n; ++i)
scanf("%d", &item[i].a);
for(int i = 0; i < n; ++i){
scanf("%d", &item[i].b);
if(item[i].b < item[i].a) cnt++;
}
sort(item, item + n);
ll sum = 0;
for(int i = 0; i < k; ++i)
sum += item[i].a;
int p;
for(p = k; p < n; ++p)
if(item[p].b - item[p].a >= 0) sum += item[p].a;
else break;
for( ; p < n; ++p)
sum += item[p].b;
printf("%lld\n", sum);
return 0;
}
D
題意:給兩個串a, b, 然後給出a串的刪除順序... 問最多刪除多少個字符之後b串仍然是a串的字串
在剛看這題的時候沒有想法, 因爲注意力在串上, 後來看了看序列, 知道好像可以二分, 隨後就寫嘛, 我是二分檢查mid的可行性, 在看樣例2的時候發現 哦... 好像不具備單調性...
和別人討論了一下說沒有單調性的題意肯定理解錯了, 我又回去讀題意, 好像真的讀錯了, 題目保證了
Sergey wants to stop her as late as possible.
It is guaranteed that the word p can be obtained by removing the letters from word t.
這裏其實說明了只要刪除後的a串只要子序列中還存在b串, 那麼就還可以繼續刪(我KMP的做法是把它當字串去做了....)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <utility>
using namespace std;
typedef long long ll;
typedef pair<int, int> pill;
const int qq = 2e5 + 10;
int n, m;
string a, b;
int num[qq];
bool id[qq];
/*void getnext(){
int i = 0, j = -1;
int len = (int)b.size();
next[0] = -1;
while(i < len){
if(j == -1 || b[i] == b[j])
next[++i] = ++j;
else j = next[j];
}
}
bool KMP(string c){
int i = 0, j = 0;
int lenc = (int)c.size(), lenb = (int)b.size();
while(i < lenc && j < lenb){
if(j == -1 || c[i] == b[j])
++i, ++j;
else j = next[j];
}
if(j == lenb) return true;
return false;
}
bool check(int k){
if((int)a.size() - k > (int)b.size()) return false;
string c;
for(int i = 0; i < k; ++i)
id[i] = num[i];
sort(id, id + k);
int p = 0;
for(int i = 0; i < (int)a.size(); ++i){
if(i + 1 == id[p]) p++;
else c += a[i];
}
if(KMP(c)) return true;
return false;
}*/
int main(){
cin >> a >> b;
n = (int)a.size();
for(int i = 0; i < n; ++i)
scanf("%d", num + i);
m = (int)b.size();
int l = 0, r = n;
int ans = 0;
while(l <= r){
int mid = (l + r) / 2;
memset(id, false, sizeof(id));
for(int i = 0; i < mid; ++i)
id[num[i] - 1] = true;
int pos = 0;
for(int i = 0; i < n; ++i){
if(id[i]) continue;
if(a[i] == b[pos]) pos++;
if(pos >= m) break;
}
if(pos >= m){
ans = mid;
l = mid + 1;
}else{
r = mid - 1;
}
}
printf("%d\n", ans);
return 0;
}