思路:很经典的题目了,不仅可以判定是否有这样的子序列,同时还可以找到有多少这样的子序列。
Code:
#include
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 11;
const int M = 1e6 + 11;
const int MOD = 1e9 + 7;
int XiaoQiao[20], Xiaohuihui[32];
int cnt[N];
char s1[] = "XiaoQiao";
char s2[ ] = "XiaoHuiHui";
bool deal(char *ss, string s){
memset(cnt, 0, sizeof(cnt));
int len = strlen(ss);
cnt[len ] = 1;
for(int i = s.size() - 1; i >= 0; i--){
for(int j = 0; ss[j]; j++) {
if(s[i] == ss[j]) {
if(cnt[j + 1] > 0)
cnt[j] = 1;
}
}
}
return cnt[0] > 0;
}
int main(int argc, char **args){
string s; cin >>s;
if(deal(s1, s) && deal(s2, s)) puts("Happy");
else puts("emm");
return 0;
}
思路:将题目中给的公式,进行化简就行了。
Code:
#include
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 11;
const int M = 1e6 + 11;
const int MOD = 1e9 + 7;
ll c[N];
int main(int argc, char **args){
int n; scanf("%d", &n);
for(int i = 0; i < n; i++){
int a,b; scanf("%d%d", &a, &b);
c[i] = b * 1ll * (a - b) * (a - b);
}
sort(c, c + n);
ll ans = 0;
for(int i = 1; i < n; i++){
ans += c[i] - c[i - 1];
}
printf("%lld\n", ans);
return 0;
}
思路:一共就两种合成装备的方式,所以我们枚举其中一个方式的次数,同时从直觉上看,如果全是某一种方式,结果不一定最优,应该是在某个中间,两种组合取得平衡,组合装备数量最多。所以问题转化为了,一个有极小值的问题,这种问题可以用三分解决。
Code:
#include
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 11;
const int M = 1e6 + 11;
const int MOD = 1e9 + 7;
ll x, y;
ll get(ll n){
return min((x - 4 * n ) / 2, (y - n ) / 3);
}
ll f(ll mid){
if(4 * mid > x || mid > y) return 0;
return mid + get(mid);
}
int main(int argc, char **args){
int t; scanf("%d", &t);
while(t--){
scanf("%lld%lld", &x, &y);
ll L, R, mid, midr;
L = 0, R = min(x / 4, y);
while(L + 2 < R){
mid = (L + R) / 2;
midr = (mid + R) / 2;
if(f(mid) > f(midr)) R = midr;
else L = mid;
}
mid = (L + R ) / 2;
printf("%lld\n", max(max(f(L), f(R)), f(mid)));
}
return 0;
}
思路:直接记忆化搜索。
Code:
#include
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 11;
const int M = 1e6 + 11;
const int MOD = 1e9 + 7;
map<ll, int> mp; // 因为值大,所以用了map来记忆历史值
int solve(ll n){
if(mp[n]) return mp[n];
if(2==solve(n / 2) || 2==solve(n - n / 2)) mp[n] = 1;
else mp[n] = 2;
return mp[n];
}
int main(int argc, char **args){
int t; scanf("%d", &t);
while(t--){
mp.clear();
mp[1] = 2;
mp[2] = 1;
mp[3] = 1;
mp[4] = 2;
ll n; scanf("%lld", &n);
puts((solve(n) == 1)? "XiaoHuiHui" :"XiaoQiao");
}
return 0;
}