贪心算法
思想
贪心
/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int M = 1010;
typedef long long ll;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
return f*x;
}
struct node{
int l,r;
}a[M];
bool cmp(node a,node b){
return a.r < b.r;
}
int ans,nr;
int main()
{
int n = read();
for (int i = 1;i <= n; i++){
a[i].l = read();
a[i].r = read();
}
sort (a + 1, a + n + 1, cmp);
for (int i = 1;i <= n; i++){
if(a[i].l >= nr){
ans++,nr = a[i].r;
}
}
printf("%d\n",ans);
return 0;
}
/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 3e4 + 10;
typedef long long ll;
int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return f * x;
}
int n, t, mp[M], s, ans;
struct Query {
int l, r, num;
} q[M];
bool cmp(Query a, Query b) {
return a.r < b.r;
}
int main() {
n = read(), t = read();
for (int i = 1; i <= t; i++) {
q[i].l = read();
q[i].r = read();
q[i].num = read();
}
sort(q + 1, q + t + 1, cmp);
for (int i = 1; i <= t; i++) {
int cnt = q[i].r;
int js = 0;
for (int j = q[i].l; j <= q[i].r; j++) {
js += mp[j];
}
if (js >= q[i].num)
continue;
for (int k = q[i].r; k >= q[i].l; k--) {
if (!mp[k]) {
js++;
ans++;
mp[k] = 1;
if (js == q[i].num)
break;
}
}
}
printf("%d", ans);
return 0;
}
/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 15010;
typedef long long ll;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
return f*x;
}
int n,l,w;
struct node{
double l,r;
}a[M];
int main()
{
int t = read();
while (t--){
int cnt = 0;
n = read(),l = read(),w = read();
memset(a, 0, sizeof(a));
for (int i = 1;i <= n; i++){
int pos = read(),r = read();
if(r * 2 <= w) continue;
double len = sqrt(r * r - w * w / 4.0);
a[++cnt].l = (pos - len) * 1.0;
a[cnt].r = (pos + len) * 1.0;
}
int ans = 0,flag = 0;
double now = 0;
while(now < l){
ans++;
double s = now;
for(int i = 1;i <= cnt; i++){
if(a[i].l <= s && a[i].r > now){
now = a[i].r;
}
}
if(now == s && s < l){
printf("-1\n");
flag = 1;
break;
}
}
if(!flag) printf("%d\n",ans);
}
return 0;
}
/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 1e4 + 4;
typedef long long ll;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
return f*x;
}
struct node{
int a,b,num;
}work[M];
int ans;
bool cmp(node x,node y){
return min(x.a , y.b) < min(y.a , x.b);
}
int tima,timb;
int main()
{
int n = read();
for(int i = 1;i <= n; i++){
work[i].a = read();
work[i].num = i;
}
for(int i = 1;i <= n; i++){
work[i].b = read();
}
sort(work + 1, work + n + 1, cmp);
for(int i = 1;i <= n; i++){
tima += work[i].a;
timb = max(tima, timb) + work[i].b;
}
cout << timb <<"\n";
for (int i = 1; i < n; i++) {
cout << work[i].num << " ";
}
cout << work[n].num;
return 0;
}
/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#define inf 0x3f3f3f3f
using namespace std;
const int M = 510;
typedef long long ll;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
return f*x;
}
int n,m,sum,minn,num,pos;
struct Game{
int tim,cos;
}g[M];
bool cmp(Game a,Game b){
if(a.tim == b.tim) return a.cos < b.cos;
return a.tim < b.tim;
}
void work(){
int cnt = 0;
for(int i = 1;i <= n; i++){
cnt++;
while(cnt > g[i].tim){
cnt--;minn = inf;
for (int j = 1;j <= i; j++){
if(g[j].cos !=0 && g[j].cos < minn){
minn = g[j].cos;pos = j;
}
}
g[pos].cos = 0;
sum += minn;
}
}
}
int main()
{
m = read(), n = read();
for(int i = 1;i <= n; i++){
g[i].tim = read();
}
for(int i = 1;i <= n; i++){
g[i].cos = read();
}
sort(g + 1,g + n + 1, cmp);
work();
printf("%d",m - sum);
}
/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 5e4 + 5;
typedef long long ll;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
return f*x;
}
int n,a[M],b[M],zz;
int main()
{
n = read();
for(int i = 1;i <= n; i++) a[i] = read(),b[i] = a[i];
sort(a + 1,a + n + 1);
sort(b + 1,b + n + 1);
for(int i = 2;i <= n + 1; i++){
a[i] = a[i - 1]*a[i] + 1;
sort(a + 1,a + n + 1);
}
for(int i = n - 1;i >= 1; i--){
b[i] = b[i + 1]*b[i] + 1;
}
cout<<a[n]-b[1]<<"\n";
return 0;
}
/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 1e5 + 5;
typedef long long ll;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
return f*x;
}
int n,m,a[M],ans,cnt;
int main()
{
n = read(),m = read();
for (int i = 1;i <= n; i++){
a[i] = read();
}
for(int i = 1;i <= n; i++){
cnt += a[i];
if(cnt == m){
ans++;
cnt = 0;
if(i == n) break;
}
if(cnt > m){
cnt = a[i];
ans++;
if(i == n) break;
}
if(i == n && cnt < m){
ans++;
}
}
printf("%d",ans);
return 0;
}
/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 1e6 + 5;
typedef long long ll;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
return f*x;
}
int n,ans = 1,last = 1;
struct node{
int l,r;
}a[M];
bool cmp(node a,node b){
return a.r < b.r;
}
int main()
{
n = read();
for(int i = 1;i <= n; i++){
a[i].l = read();
a[i].r = read();
}
sort(a + 1,a + n + 1,cmp);
for(int i = 2;i <= n; i++){
if(a[i].l >= a[last].r){
last = i;
ans++;
}
}
cout<<ans;
return 0;
}
思想:
按分数从大到小排序,绕后找按时间从小到大做作业;
实现:
枚举这个作业的时间,看他这个时间之前的时间(包括这个时间)有没有被占用过
如果时间全占用过个这个作业不合法,继续枚举下一个
如果还有时间没被占用过,就贪心枚举离这个时间最近的没有用过的时间来做这个作业
/*
work by:Ariel_
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
//==========================
const int A = 1e3 + 2;
const int B = 1e4 + 2;
const int C = 1e5 + 2;
const int D = 1e6 + 2;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){
if(c == '-')f = -1;c = getchar();}
while(c >= '0'&& c <= '9'){x = x*10 + c - '0',c = getchar();}
return x*f;
}
//===============================================================
struct node{
int tim,sore;
}a[D];
bool cmp(node a,node b){
if(a.sore == b.sore) return a.tim > b.tim;
return a.sore > b.sore;
}
int n,ans,now,vis[D];
int main(){
n = read();
for (int i = 1;i <= n; i++){
a[i].tim = read();
a[i].sore = read();
}
sort(a + 1,a + n + 1,cmp);
for(int i = 1;i <= n; i++){
if(a[i].tim <= now) continue;
int f = 0;
for(int j = a[i].tim;j >= 1; j--){
if(!vis[j]){
vis[j] = 1;
f = 1;
ans += a[i].sore;
break;
}
}
if(!f) now = a[i].tim;
}
printf("%d",ans);
}
思想
优先队列,贪心
/*
work by:Ariel_
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
//==========================
const int A = 1e3 + 2;
const int B = 1e4 + 2;
const int C = 1e5 + 2;
const int D = 1e6 + 2;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){
if(c == '-')f = -1;c = getchar();}
while(c >= '0'&& c <= '9'){x = x*10 + c - '0',c = getchar();}
return x*f;
}
//===============================================================
struct node{
int f,num;
bool operator < (node x)const {
return f < x.f;
}
}a[B];
priority_queue<node>q;
int n,h,d[B],t[B],ans;
int main(){
n = read(),h = read();
h *= 12;//都是以五分钟为单位,所以这里进行个特殊处理
for (int i = 1;i <= n; i++){
a[i].f = read();
a[i].num = i;
}
for (int i = 1;i <= n; i++){
d[i] = read();
}
for (int i = 1;i < n; i++){
t[i] = read();
}
for (int i = 1;i <= n; i++){
h -= t[i-1];
while(!q.empty())q.pop();
for(int j = 1;j <= i; j++){
q.push(a[j]);
}
int now = 0;
for(int j = 1;j <= h; j++){
node s;
s = q.top();
if(s.f > 0)now += s.f;
s.f -= d[s.num];
q.pop();
q.push(s);
}
ans = max(now,ans);
}
printf("%d",ans);
}
思想:
均分纸牌思想,贪心
/*
work by:Ariel_
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
#define inf 0x3f3f3f3f
#define int long long
using namespace std;
typedef long long ll;
//==========================
const int A = 1e3 + 2;
const int B = 1e4 + 2;
const int C = 1e5 + 2;
const int D = 1e6 + 2;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){
if(c == '-')f = -1;c = getchar();}
while(c >= '0'&& c <= '9'){x = x*10 + c - '0',c = getchar();}
return x*f;
}
//===============================================================
int n,a[D],sum,res,ans,f[D];
signed main(){
n = read();
for(int i = 1;i <= n; i++){
a[i] = read();
sum += a[i];
}
res = sum/n;
for(int i = 1;i <= n; i++){
f[i] = f[i - 1] + a[i] - res;
}
sort(f + 1,f + n + 1);
for(int i = 1;i <= n; i++)ans += abs(f[i] - f[(n >> 1) + 1]);
printf("%lld",ans);
}
思想
二分板子
/*
work by:Ariel_
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#define orz cout<<"Ak ioi"<<endl;
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
//==========================
const int A = 1e3 + 2;
const int B = 1e4 + 2;
const int C = 1e5 + 2;
const int D = 1e6 + 2;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){
if(c == '-')f = -1;c = getchar();}
while(c >= '0'&& c <= '9'){x = x*10 + c - '0',c = getchar();}
return x*f;
}
//===============================================================
int n,m,a[C],maxn,ans,zz,l = 1,r;
bool juge(int x){
int js = 1,last = 1;
for(int i = 2;i <= n; i++){
if(a[i] - a[last] >= x){
js++;last = i;
}
}
if(js >= m) return true;
else
return false;
}
void mid_search(){
r = a[n] - a[1];
while(l <= r){
int mid = (l + r)>>1;
if(juge(mid)) l = mid + 1;
else r = mid - 1;
}
}
int main(){
n = read(),m = read();
for(int i = 1;i <= n; i++){
a[i] = read();
}
sort(a + 1,a + n + 1);
mid_search();
printf("%d",l - 1);
}
10012. 「一本通 1.2 例 2」Best Cow Fences
思想
/*
work by:Ariel_
*/
/*mind:
枚举平均值,然后将每数都减去平均值
判断区间是否符合大于等于平均值
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
#define int long long
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
//==========================
const int A = 1e3 + 2;
const int B = 1e4 + 2;
const int C = 1e5 + 2;
const int D = 1e6 + 2;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){
if(c == '-')f = -1;c = getchar();}
while(c >= '0'&& c <= '9'){x = x*10 + c - '0',c = getchar();}
return x*f;
}
//===============================================================
int n,l,a[C],max_,b[C];
bool cheak(int x){
int minn = inf;
for(int i = 1;i <= n; i++){
b[i] = a[i] + b[i - 1]- x;
if(i >= l){
minn = min(minn,b[i - l]);
if(b[i] > minn)
return true;
}
}
return false;
}
signed main(){
n = read(),l = read();
for (int i = 1;i <= n; i++){
a[i] = read();
a[i] =a[i]*10000;
max_ = max(max_,a[i]);
}
int l = 1,r = max_;
while(l <= r){
int mid = (l + r)>>1;
if(cheak(mid)) l = mid + 1;
else r = mid - 1;
}
printf("%d",l/10);
}
思想:
三分
/*
work by:Ariel_
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
//==========================
const int A = 1e3 + 2;
const int B = 1e4 + 2;
const int C = 1e5 + 2;
const int D = 1e6 + 2;
const double jd = 1e-9;
//===============================================================
int T, n, a[C], b[C], c[C];
double check(double x) {
double maxn_ = 0;
for (int i = 1; i <= n; i++)
maxn_ = max(maxn_, a[i] * x * x * 1.0 + b[i] * x * 1.0 + c[i] * 1.0);
return maxn_;
}
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d %d %d", &a[i], &b[i], &c[i]);
}
double l = 0, r = 1000;
while (r - l > jd) {
double mid1, mid2;
mid1 = l + (r - l) / 3.0;
mid2 = r - (r - l) / 3.0;;
if (check(mid1) < check(mid2))
r = mid2;
else
l = mid1;
}
printf("%.4lf\n", check(l));
}
}
思想:
二分板子,注意边界处理
/*
work by:Ariel_
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
//==========================
const int A = 1e3 + 2;
const int B = 1e4 + 2;
const int C = 1e5 + 2;
const int D = 1e6 + 2;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){
if(c == '-')f = -1;c = getchar();}
while(c >= '0'&& c <= '9'){x = x*10 + c - '0',c = getchar();}
return x*f;
}
//===============================================================
int n,m,a[C],maxn_,l,r,ans;;
bool check(int x){
int sum = 0,tot = 1;
for(int i = 1;i <= n; i++){
if(sum + a[i] > x){
sum = 0;
tot++;
}
sum += a[i];
}
return tot <= m;
}
int main(){
n = read(), m = read();
for(int i = 1;i <= n; i++){
a[i] = read();
r += a[i];
l = max(l,a[i]);
}
while(l <= r){
int mid = (l + r)>>1;
if(check(mid)){
r = mid - 1;
ans = mid;
}
else l = mid + 1;
}
printf("%d",ans);
}
思想
图论,判断图是否联通:最近公共祖先,并查集
二分枚举时间
/*
work by:Ariel_
*/
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
//==========================
const int A = 1e9;
const int B = 1e4 + 2;
const int C = 1e5 + 2;
const int D = 1e6 + 2;
int read(){
int x = 0,f = 1;char c = getchar();
while(c < '0'||c > '9'){
if(c == '-')f = -1;c = getchar();}
while(c >= '0'&& c <= '9'){x = x*10 + c - '0',c = getchar();}
return x*f;
}
//===============================================================
int fa[55];
int find(int x){
return (fa[x] == x) ? fa[x]:fa[x] = find(fa[x]);
}
struct node{
int xx,yy;
}a[55];
int n;
int main(){
n = read();
for(int i = 1;i <= n; i++){
a[i].xx = read();
a[i].yy = read();
}
int l = 0,r = A,ans = 0;
while(l <= r){
int mid = (l + r) >> 1;
for(int i = 1;i <= n; i++) fa[i] = i;//初始化
for (int i = 1;i <= n; i++){//两两枚举点看是否能在规定时间联通
for (int j = i + 1;j <= n; j++){
int dis = abs(a[j].xx - a[i].xx) + abs(a[j].yy - a[i].yy);//曼哈顿距离
if(dis <= mid * 2){//因为是两个点,所以扩散速度应该为两倍
int fa1 = find(i);
int fa2 = find(j);
if(fa1 != fa2) fa[fa1] = fa2;//把两个点连起来
}
}
}
int cnt = 0;
for(int i = 1;i <= n; i++){
if(fa[i] == i){
cnt++;
}
}
if(cnt == 1){//图能联通
ans = mid;
r = mid - 1;
}
else {
l = mid + 1;
}
}
printf("%d",ans);
}