题目来源:https://codeforces.com/contest/1282
脑速不够,差点掉分了,勉强上蓝,算是圣诞礼物了叭~
最可怕的是 发生了暑假一样的错误:
两个int型变量相乘然后爆了,希望以后不会再犯了!!!
这题可以说考的就是求x轴上两线段的重复的长度,但是我居然debug了18分钟…
我当时AC的代码 枚举每一种情况 (我是码农)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;
const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;
int n, m;
template<class T>
inline void read(T &x) {
char c;
x = 1;
while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
T res = c - '0';
while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
x *= res;
}
int main() {
int t;
r(t);
while(t--){
int a,b,c,r;
rrr(a,b,c); r(r);
if(a>b) swap(a,b);
int ans=0;
int x=c-r;
int y=c+r;
if(x<=a&&b<=y){
cout<<0<<endl;
continue;
}
else if(x<=a&&a<=y){
cout<<b-y<<endl;
continue;
}
else if(x<=b&&b<=y){
cout<<x-a<<endl;
continue;
}
if(a<=x&&y<=b){
cout<<b-a-(y-x)<<endl;
}
else{
cout<<b-a<<endl;
}
}
return 0;
}
优化后简单的代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;
const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;
int n, m;
template<class T>
inline void read(T &x) {
char c;
x = 1;
while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
T res = c - '0';
while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
x *= res;
}
int main() {
int t;
r(t);
while(t--){
int a,b,c,r;
rrr(a,b,c); r(r);
int x=c-r,y=c+r;
if(a>b) swap(a,b);
cout<<b-a-max(0,min(b,y)-max(a,x))<<endl;
}
return 0;
}
(Easy & Hard Version)
把价格排序之后不难发现 想用最少的钱买最多的肯定是把最靠前的都给买了
我把它当做dp处理了 dp[ i ]表示买前i个最少花多少钱
转移方程dp[i] = min(dp[i], dp[i - k] + f[i])
然后注意 dp[ i ] 不是逐渐增大的 ,我们要找最大的满足的i就ok了 故要倒着找
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;
const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;
int n, m;
int f[N<<2];
LL dp[N<<2];
template<class T>
inline void read(T &x) {
char c;
x = 1;
while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
T res = c - '0';
while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
x *= res;
}
int main() {
int t;
r(t);
while(t--) {
r(n);
r(m);
int k;
r(k);
FOR(i, 1, n) r(f[i]);
sort(f + 1, f + n + 1);
int ans = 0;
dp[0] = 0;
for (int i = 1; i <= n; i++) {
dp[i] = dp[i - 1] + f[i];
if (i >= k) {
dp[i] = min(dp[i], dp[i - k] + f[i]);
}
}
for(int i=n;i>=0;i--){
if(m>=dp[i]){
cout<<i<<endl;
break;
}
}
}
return 0;
}
这题考虑起来就是 先对ti 排序 ,每次考虑ti-1的时间能不能容纳前i-1个任务完成,能完成还要看能不能容纳i之后的任务(先考虑简单任务,再考虑复杂任务,这也是贪心的一部分)
可怜,我再一次因为爆int而过了pretest没过终测,希望长点记性~
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;
const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;
int n, m;
struct node
{
int x,y;
}f[N<<2];
bool cmp(node a,node b)
{
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
template<class T>
inline void read(T &x) {
char c;
x = 1;
while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
T res = c - '0';
while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
x *= res;
}
int main() {
int t;
r(t);
while(t--) {
int x,y;
rrr(n,m,x); r(y);
int n0=0,n1=0;
FOR(i,1,n){
r(f[i].y);
if(f[i].y) n1++;
else n0++;
}
FOR(i,1,n) r(f[i].x);
sort(f+1,f+n+1,cmp);
int ans=0;
LL need=0;
f[n+1].x=m+1;
f[n+1].y=2;
f[0].x=0;
f[0].y=2;
for(int i=0;i<=n;i++){
if(f[i].y==0){
need+=x;
n0--;
}
else if(f[i].y==1){
need+=y;
n1--;
}
if(need>m) break;
else if(need<=f[i+1].x-1) {
int now=i;
LL res=f[i+1].x-1-need;
if(1ll*x*n0>res){
now+=res/x;
}
else{
now+=n0;
res-=1ll*n0*x;
if(1ll*y*n1>res){
now+=res/y;
}
else{
now+=n1;
}
}
ans=max(ans,now);
}
}
cout<<ans<<endl;
}
return 0;
}
这题是一道特殊的人机互动题,什么是互动题自行查找
我也是比赛前一小时才知道什么是互动题的,可惜前面卡太久了,这些题没时间做了 555 算了放一个介绍链接吧
怎么在n+2次查找中找到答案呢?这个n+2很有深意哦~
思路如下:
第一次 问 300个a 得 q1
第二次 问 300个b 得 q2
想一想 N-q1是不是最终的a的个数 N-q2是不是最终的b的个数 总长度n=a+b
然后假设最终答案为 1个b加n-1个a ,此时如果真正的答案的第一个字符确实是b 那会返回b-1 否则返回b+1 通过这种区别来往后判断这个位置是b还是a
值得注意的是你写出的代码可能最多循环了n+3次 还需要特殊处理 见代码 不细说
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;
const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;
int n, m;
template<class T>
inline void read(T &x) {
char c;
x = 1;
while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
T res = c - '0';
while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
x *= res;
}
int hhh(string s)
{
cout<<s<<endl;
int op;
r(op);
if(op==0) exit(0);
return op;
}
int main() {
int LEN=300;
int rest=hhh(string(LEN,'a'));
n=2*LEN-rest-hhh(string(LEN,'b'));
int a=LEN-rest,b=n-a;
string ans(n,'a');
int tmp=b;
for(int i=0;i<n-1;i++){
ans[i]='b';
if(hhh(ans)>tmp){
ans[i]='a';
}
else tmp--;
}
if(tmp) ans[n-1]='b';
hhh(ans);
return 0;
}