目录
左移右移
思路:
代码:
买二增一
思路:
代码:
松散子序列
思路:
代码:
填充
思路:
代码 :
有奖问答
思路:
代码:
更小的数
思路:
代码:
左移右移
思路:
1、用权重的思路,初始权值为该数值
2、将改变权值初始为cval=n+1,当之后出现某数,
为L则,权值赋为-cval, cval++;
为R则,权值赋为cval,cval++。
3、最后根据权值排序
代码:
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int num;
int val;
}a[200010];
bool cmp(node a,node b)
{
return a.val < b.val;
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
a[i].num = i;
a[i].val = i;
}
int cval = n + 1;
while (m--)
{
int t;
char b;
cin >> b >> t;
if (b == 'L')
{
a[t].val = -cval;
cval++;
}
else
{
a[t].val = cval;
cval++;
}
}
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i++)
cout << a[i].num << " ";
}
买二增一
思路:
1、用一个优先队列q(大根堆)存储价格
2、再用一个队列cost存储,每买两个可以赠送的最大价格,当cost的队头大于等于q的队头,说明该q队头价格可以赠送,直接出队。
3、用ans存储总价格
代码:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{
priority_queue<ll> q, cost;
int n,t;
cin >> n;
while (n--)
cin >> t, q.push(t);
ll ans = 0;
while (!q.empty())
{
while (!cost.empty() && !q.empty() && cost.top() >= q.top())
cost.pop(), q.pop();
int maxp=0, minp=0;
if (!q.empty())
maxp = q.top(), q.pop();
while (!cost.empty() && !q.empty() && cost.top() >= q.top())
cost.pop(), q.pop();
if (!q.empty())
minp = q.top(), q.pop();
//cout << maxp << " " << minp;
ans += maxp + minp;
cost.push(minp / 2);
}
cout << ans;
}
松散子序列
思路:
1、用一个动态规划
代码:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{
string s;
cin >> s;
int dp[1000005] = { 0 };
dp[0] = s[0] - 'a' + 1;
dp[1] = max(dp[0], s[1] - 'a' + 1);
for (int i = 2; i < s.length(); i++)
{
dp[i] = max(dp[i - 1], dp[i - 2] + (s[i] - 'a' + 1));
}
cout << dp[s.length() - 1];
}
填充
思路:
1、用flag记录是否是00或者11子串
2、从第二个开始,用这一个与前一个比较是否相等(偶数比奇数)
代码 :
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{
string s;
cin >> s;
int flag[10000005];
ll ans = 0;
for (int i =1; i < s.length(); i++)
{
if (flag[i - 1])
continue;
if (s[i] == s[i - 1] || s[i - 1] == '?' || s[i] == '?')
{
flag[i] = 1;
ans++;
}
}
cout << ans;
}
有奖问答
思路:
1、用动态规划
2、分两种情况:
第一种:第i题没有做对,方案数等于i-1题的所有方案数和
第二种:第i题做对,得到j分,方案数等于上一题方案数得j-10分的方案数
3、当得分为70时,加上该可能的所有方案数
代码:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{
ll ans = 0;
int dp[35][100] = { 0 };
dp[1][0] = dp[1][10] = 1;//第一题可能得10分或者0分
for(int i=2;i<=30;i++)//从第二题开始到三十题
for (int j = 0; j <= 90; j += 10)//0到90的方案数
{
if (j == 0)//该题没做对,方案数等于i-1题的所有方案数
{
for (int k = 0; k <= 90; k += 10)
{
dp[i][0] += dp[i - 1][k];
}
}
else//该题做对了,方案数等于上一题做完该题得多少分-10的方案数
{
dp[i][j] = dp[i - 1][j - 10];
if (j == 70) ans += dp[i][j];//等于70,方案数加上
}
}
cout << ans;
}
更小的数
思路:
1、用动态规划
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
int main()
{
string s;
cin >> s;
int dp[5010][5010];
s = " " + s;
for (int i = 2; i < s.length(); i++)
{
for (int j = 1; j + i - 1 < s.length(); j++)
{
int l = j, r = j + i - 1;
if (s[l] == s[r])
dp[l][r] = dp[l + 1][r - 1];
else if (s[l] < s[r])
dp[l][r] = 0;
else
dp[l][r] = 1;
}
}
ll ans = 0;
for (int i = 1; i < s.length(); i++)
for (int j = i; j < s.length(); j++)
ans += dp[i][j];
cout << ans;
}