题意:给一个数组有n个数,问是否能找出三个数,使得以三个数为边长的边无法构成一个三角形。
思路:因为题目输入已经是有序的,所以直接用最小的两个和最大的数进行判断即可。只要v[0]+v[1]<=v[n-1]就存在。
/**
* Created by jiangxiaoju on 2020/8/14 22:31.
*/
#include
using namespace std;
#define mp(a, b) make_pair(a, b)
#define mid ((l + r) >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
typedef long long ll;
typedef pair<ll, int> pli;
typedef pair<int, int> pii;
typedef pair<int, double> pid;
typedef pair<double, double> pdd;
typedef pair<double, int> pdi;
typedef pair<ll, double> pld;
typedef pair<double, ll> pdl;
typedef pair<ll, ll> pll;
const long long INF = 1e15;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
template<class T>
bool isPrime(T x) {
if (x <= 1)
return false;
if (x == 2)
return true;
if (x % 2 == 0)
return false;
T m = sqrt(x);
for (T i = 3; i <= m; i += 2) {
if (x % i == 0)
return false;
}
return true;
}
template<class T>
T gcd(T m, T n) { return m % n == 0 ? n : gcd(n, m % n); }
ll qpow(ll x, ll y) {
ll res = 1;
while (y) {
if (y & 1)
res = res * x;
x = x * x;
y >>= 1;
}
return res;
}
template<class T>
ll qpow(ll x, ll y, T mod) {
ll res = 1;
while (y) {
if (y & 1)
res = res * x % mod;
x = x * x % mod;
y >>= 1;
}
return res;
}
int main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<long long> v(n);
for (auto &val:v) {
cin >> val;
}
int i;
int flag = 1;
if (v[0] + v[1] <= v[n - 1]) {
cout << 1 << ' ' << 2 << ' ' << n << endl;
flag = 0;
}
if (flag)cout << -1 << endl;
}
return 0;
}
题意:有一个只包含0和1的字符串,Alice和Bob轮流对字符串进行删除操作。每次可以删除至少一个相同连续的字符。他们最后的得分是删除字符1的次数。问Alice最后最多可以得多少分。(玩家都是采取最有操作)
思路:既然要尽可能的多删除1,那么每次删除的时候肯定是优先选择连续的1进行删除。所以只要记录每段连续1的长度,然后排个序,进行累加即可。
/**
* Created by jiangxiaoju on 2020/8/14 22:31.
*/
#include
using namespace std;
#define mp(a, b) make_pair(a, b)
#define mid ((l + r) >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
typedef long long ll;
typedef pair<ll, int> pli;
typedef pair<int, int> pii;
typedef pair<int, double> pid;
typedef pair<double, double> pdd;
typedef pair<double, int> pdi;
typedef pair<ll, double> pld;
typedef pair<double, ll> pdl;
typedef pair<ll, ll> pll;
const long long INF = 1e15;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
template<class T>
bool isPrime(T x) {
if (x <= 1)
return false;
if (x == 2)
return true;
if (x % 2 == 0)
return false;
T m = sqrt(x);
for (T i = 3; i <= m; i += 2) {
if (x % i == 0)
return false;
}
return true;
}
template<class T>
T gcd(T m, T n) { return m % n == 0 ? n : gcd(n, m % n); }
ll qpow(ll x, ll y) {
ll res = 1;
while (y) {
if (y & 1)
res = res * x;
x = x * x;
y >>= 1;
}
return res;
}
template<class T>
ll qpow(ll x, ll y, T mod) {
ll res = 1;
while (y) {
if (y & 1)
res = res * x % mod;
x = x * x % mod;
y >>= 1;
}
return res;
}
int main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
string str;
cin >> str;
int ans1 = 0;
int ans2 = 0;
vector<int> v;
int i;
int cnt = 1;
for (i = 0; i < str.size(); i++) {
if (str[i] == '1') {
cnt = 0;
while (i < str.size() && str[i] == '1') {
i++;
cnt++;
}
v.push_back(cnt);
}
}
sort(v.begin(),v.end(),greater<int>());
for(i=0;i<v.size();i+=2){
ans1+=v[i];
}
cout << ans1 << endl;
}
return 0;
}
题意:有一个数组,数组中每个元素只包含0-9这10中数字。问有多少个子数组满足子数组和等于该子数组长度。
思路:对数组中每个元素都-1。这样就可以把求子数组和等于该子数组长度转换成 有多少个子数组和为0。根据前缀和的性值 如果 sum[i]==sum[j] (i>j)的话,那么[j+1,i]这个区间中的和肯定是为0的。任意两个相等的前缀和之间都可以有一个区间和为0。所以假设前缀和为A的共有B个。那么区间和为0的个数为(B-1)*B/2。
/**
* Created by jiangxiaoju on 2020/8/14 22:57.
*/
#include
using namespace std;
#define mp(a, b) make_pair(a, b)
#define mid ((l + r) >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
typedef long long ll;
typedef pair<ll, int> pli;
typedef pair<int, int> pii;
typedef pair<int, double> pid;
typedef pair<double, double> pdd;
typedef pair<double, int> pdi;
typedef pair<ll, double> pld;
typedef pair<double, ll> pdl;
typedef pair<ll, ll> pll;
const long long INF = 1e15;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
template<class T>
bool isPrime(T x) {
if (x <= 1)
return false;
if (x == 2)
return true;
if (x % 2 == 0)
return false;
T m = sqrt(x);
for (T i = 3; i <= m; i += 2) {
if (x % i == 0)
return false;
}
return true;
}
template<class T>
T gcd(T m, T n) { return m % n == 0 ? n : gcd(n, m % n); }
ll qpow(ll x, ll y) {
ll res = 1;
while (y) {
if (y & 1)
res = res * x;
x = x * x;
y >>= 1;
}
return res;
}
template<class T>
ll qpow(ll x, ll y, T mod) {
ll res = 1;
while (y) {
if (y & 1)
res = res * x % mod;
x = x * x % mod;
y >>= 1;
}
return res;
}
int main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> v(n + 10);
int i;
string str;
cin >> str;
vector<int> sum(n + 1);
for (i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + str[i - 1] - '0' - 1;
}
int j;
int cnt = 0;
map<ll, ll> mmid;
mmid[0] = 1;
ll ans = 0;
for (i = 1; i <= n; i++) {
mmid[sum[i]]++;
}
for (auto[a, b]:mmid) {
ans+=(b*(b-1)/2);
}
cout << ans << endl;
}
return 0;
}
题意:有多组R,B,G三种颜色的彩色棍。R对红色棍,第一对的长度为r1,第二对的长度为r2,…,第R对的长度为rR;G对绿色棍,第一对的长度为g1,第二对的长度为g2,…,第G对的长度为gG;B对蓝色棍,第一对长度为b1,第二对长度为b2,…,第二对长度为bB; 每次可以拿两对不同颜色的棍子组成一个矩形。每对棍子只能使用一次。问最后组成的所有矩形面积和是多少。
思路:看到这题一开始想到的是贪心。对每中颜色的棍子按长度排个序。然后每次取长度最大的不同颜色棍子进行组合,结果见代码中附带的测试数据,第一个就过不去了。所以这题很像是DP。最后用记忆化搜索莽了一发。
先对每种颜色的棍子按从小到大的顺序排个序。
定义一个dp[220][220][220],dp[r][g][b]表示每种棍子分别剩下r,g,b队时的最优解。只要棍子数量不为0。就从三种组合里面取一个最后的。r和g,r和b,b和g。
/**
* Created by jiangxiaoju on 2020/8/14 22:57.
*/
#include
using namespace std;
#define mp(a, b) make_pair(a, b)
#define mid ((l + r) >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
typedef long long ll;
typedef pair<ll, int> pli;
typedef pair<int, int> pii;
typedef pair<int, double> pid;
typedef pair<double, double> pdd;
typedef pair<double, int> pdi;
typedef pair<ll, double> pld;
typedef pair<double, ll> pdl;
typedef pair<ll, ll> pll;
const long long INF = 1e15;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
template<class T>
bool isPrime(T x) {
if (x <= 1)
return false;
if (x == 2)
return true;
if (x % 2 == 0)
return false;
T m = sqrt(x);
for (T i = 3; i <= m; i += 2) {
if (x % i == 0)
return false;
}
return true;
}
template<class T>
T gcd(T m, T n) { return m % n == 0 ? n : gcd(n, m % n); }
ll qpow(ll x, ll y) {
ll res = 1;
while (y) {
if (y & 1)
res = res * x;
x = x * x;
y >>= 1;
}
return res;
}
template<class T>
ll qpow(ll x, ll y, T mod) {
ll res = 1;
while (y) {
if (y & 1)
res = res * x % mod;
x = x * x % mod;
y >>= 1;
}
return res;
}
struct cmp {
bool operator()(const vector<int> &v1, const vector<int> &v2) {
if (v1.size() != v2.size())return v1.size() < v2.size();
else {
return v1[v1.size() - 1] < v2[v2.size() - 1];
}
}
};
ll dp[220][220][220];
vector<int> G, R, B;
ll dfs(int r, int g, int b) {
if (dp[r][g][b] != -1) return dp[r][g][b];
ll res = 0;
if (((r == 0) + (g == 0) + (b == 0)) >= 2) {
res = 0;
}
if (r && g) {
res = max(res, dfs(r - 1, g - 1, b) + R[r - 1] * G[g - 1]);
}
if (b && g) {
res = max(res, dfs(r, g - 1, b - 1) + B[b - 1] * G[g - 1]);
}
if (r && b) {
res = max(res, dfs(r - 1, g, b - 1) + R[r - 1] * B[b - 1]);
}
return dp[r][g][b] = res;
}
int main() {
ios::sync_with_stdio(false);
memset(dp, -1, sizeof(dp));
int r, g, b;
cin >> r >> g >> b;
R.resize(r);
G.resize(g);
B.resize(b);
for (auto &val:R) {
cin >> val;
}
for (auto &val:G) {
cin >> val;
}
for (auto &val:B) {
cin >> val;
}
sort(R.begin(), R.end());
sort(G.begin(), G.end());
sort(B.begin(), B.end());
cout << dfs(r, g, b) << endl;
return 0;
}
/**
* 2 1 1
* 5 5
* 8
* 9
*
*
* 3 1 1
* 1 1 1
* 100
* 100
*/