A.Toda 2
思路:可以有二分来得到最后的数值,然后每次排序去掉最大的两个,或者3个(奇数时)。
1 /************************************************ 2 *Author* : Ray(siludose) 3 *Created Time* : 2016��10��24�� ����һ 15ʱ00��28�� 4 **Problem** : /media/ray/708898B888987E72/Users/Administrator/Desktop/2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)/erfen_a.cpp 5 **Analyse** : 6 **Get** : 7 **Code** : 8 *********************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 #include <vector> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <string> 19 #include <cmath> 20 #include <cstdlib> 21 #include <ctime> 22 #include <stack> 23 using namespace std; 24 typedef pair<int, int> pii; 25 typedef long long ll; 26 typedef unsigned long long ull; 27 #define pri(a) printf("%d ",(a)) 28 #define xx first 29 #define yy second 30 const int mod = int(1e9) + 7, INF = 0x3f3f3f3f; 31 const int maxn = 110; 32 33 int a[maxn],n; 34 35 struct node{ 36 int i,v; 37 }b[maxn]; 38 vector<string> outp; 39 bool cmp(const node &a,const node &b){ 40 return a.v>b.v; 41 } 42 bool check(int tar){ 43 if(tar==0)return true; 44 for(int i=1;i<=n;i++)b[i]=(node){i,a[i]-tar}; 45 sort(b+1,b+1+n,cmp); 46 47 int leftsu=0; 48 for(int i=2;i<=n;i++)leftsu+=b[i].v; 49 if(leftsu<b[1].v)return false; 50 if(n==2&&(b[1].v+leftsu)%2!=0)return false; 51 return true; 52 } 53 void add(int i,int j){ 54 string t; 55 for(int i=0;i<n;i++)t+='0'; 56 t[i-1]=t[j-1]='1'; 57 outp.push_back(t); 58 } 59 void add(int i,int j,int k){ 60 string t; 61 for(int i=0;i<n;i++)t+='0'; 62 t[i-1]=t[j-1]=t[k-1]='1'; 63 outp.push_back(t); 64 } 65 void out(int tar){ 66 printf("%d ",tar); 67 if(tar==0){ 68 for(int i=1;i<n;i++)for(int j=0;j<100;j++)add(i,i+1); 69 for(int j=0;j<100;j++)add(n,1); 70 }else{ 71 for(int i=1;i<=n;i++)b[i]=(node){i,a[i]-tar}; 72 sort(b+1,b+1+n,cmp); 73 74 int su=0; 75 for(int i=1;i<=n;i++)su+=b[i].v; 76 77 if(su%2==1){ 78 add(b[1].i,b[2].i,b[3].i); 79 b[1].v--;b[2].v--;b[3].v--; 80 sort(b+1,b+1+n,cmp); 81 } 82 83 while(b[1].v){ 84 add(b[1].i,b[2].i); 85 b[1].v--; 86 b[2].v--; 87 sort(b+1,b+1+n,cmp); 88 } 89 } 90 cout<<outp.size()<<endl; 91 for(int i=0;i<outp.size();i++){ 92 cout<<outp[i]<<endl; 93 } 94 } 95 96 int main(void) 97 { 98 scanf("%d",&n); 99 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 100 int l=0,r=100;for(int i=1;i<=n;i++)if(a[i]<r)r=a[i]; 101 while(l<=r){ 102 int m=l+r>>1; 103 if(check(m))l=m+1; 104 else r=m-1; 105 } 106 out(r); 107 return 0; 108 }
1 /************************************************ 2 *Author* : Ray(siludose) 3 *Created Time* : 2016年10月24日 星期一 17时20分20秒 4 **Problem** : cf730b.cpp 5 **Analyse** : 6 **Get** : 7 **Code** : 8 *********************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 #include <vector> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <string> 19 #include <cmath> 20 #include <cstdlib> 21 #include <ctime> 22 #include <stack> 23 using namespace std; 24 typedef pair<int, int> pii; 25 typedef long long ll; 26 typedef unsigned long long ull; 27 #define pri(a) printf("%d ",(a)) 28 #define xx first 29 #define yy second 30 const int mod = int(1e9) + 7, INF = 0x3f3f3f3f; 31 const int maxn = 1e5 + 13; 32 33 bool com(int i,int j){ 34 cout<<"? "<<i<<" "<<j<<endl; 35 char c; 36 cin>>c; 37 return c=='<'; 38 } 39 int t,n; 40 int main(void) 41 { 42 cin>>t; 43 while(t--){ 44 cin>>n; 45 int ma,mi; 46 if(n%2==1) 47 ma=mi=1; 48 else 49 if(com(1,2)) mi=1,ma=2; 50 else mi=2,ma=1; 51 52 for(int i=n%2==1?2:3;i<=n;i+=2){ 53 if(com(i,i+1)){ 54 if(com(i,mi))mi=i; 55 if(com(ma,i+1))ma=i+1; 56 }else{ 57 if(com(i+1,mi))mi=i+1; 58 if(com(ma,i))ma=i; 59 } 60 } 61 cout<<"! "<<mi<<" "<<ma<<endl; 62 } 63 return 0; 64 }
C.Bulmart
给1个n点m边简单图(可能不是联通分量),每条边一样长度(就说花费时间一样),一些边上有商店,第i个商店放ci点,有价格pi的ki个货物,q次询问,目的地gi需要ri个货物且不能花超过ai,求能否满足此询问,能的话求出最小的运送最长时间
一开始想用网络流做的,发现其实只是取多个最小值问题就直接转问题思路。做法是对每次询问,从目的地跑bfs,把对应位置商店置一下距离,二分路程求最小路程可满足需求
为了在找到解时直接return,预处理时商店列表以单价递增的方式排序
这里有个问题,就是询问这里是o(qwlogn)+o(qw),1000*5000*12=6*10^7,可能1500ms不能满足,而且@Deep♂Dark♂Fantasy ,为什么你们是o(qwlogn)+o(nw)的还能过?
补:ACdream回答是CF 1s=2~3*10^8次运算,所以能过,顺带HDU 1s=10^8次运算
1 /************************************************ 2 *Author* : Ray(siludose) 3 *Created Time* : 2016年10月25日 星期二 15时44分33秒 4 **Problem** : cf730c.cpp 5 **Analyse** : 6 **Get** : 7 **Code** : 8 *********************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 #include <vector> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <string> 19 #include <cmath> 20 #include <cstdlib> 21 #include <ctime> 22 #include <stack> 23 using namespace std; 24 typedef pair<int, int> pii; 25 typedef __int64 ll; 26 typedef unsigned long long ull; 27 #define pri(a) printf("%d ",(a)) 28 #define xx first 29 #define yy second 30 const int mod = int(1e9) + 7, INF = 0x3f3f3f3f; 31 const int maxn = 5e3 + 13; 32 33 int n,m; 34 int w,u,v,q,r,g,a; 35 vector<int> to[maxn]; 36 queue<int> que; 37 int dist[maxn][maxn]; 38 struct St{ 39 ll c,k,p; 40 }st[maxn]; 41 vector<struct St>tt; 42 bool cmp(struct St a,struct St b){ 43 return a.p<b.p; 44 } 45 void bfs(int beg) 46 { 47 memset(dist[beg],-1,sizeof(dist[beg])); 48 dist[beg][beg]=0; 49 que.push(beg); 50 while(!que.empty()){ 51 int te=que.front();que.pop(); 52 for(int i=0;i<to[te].size();i++){ 53 int nex=to[te][i]; 54 if(dist[beg][nex]==-1){ 55 dist[beg][nex]=dist[beg][te]+1; 56 que.push(nex); 57 } 58 } 59 } 60 } 61 bool check(int beg,int dis,int rr,int aa) 62 { 63 tt.clear(); 64 for(int i=1;i<=w;i++) 65 if(dist[beg][st[i].c]<=dis&&dist[beg][st[i].c]!=-1) 66 tt.push_back(st[i]); 67 ll num=0,ans=0; 68 for(int i=0;i<tt.size();i++){ 69 if((tt[i].k+num)<=rr)num+=tt[i].k,ans+=tt[i].k*tt[i].p; 70 else ans+=(rr-num)*tt[i].p,num=rr; 71 if(num==rr&&ans<=aa)return true; 72 } 73 return false; 74 } 75 int main(void) 76 { 77 scanf("%d%d",&n,&m); 78 for(int i=1;i<=m;i++){ 79 scanf("%d%d",&u,&v); 80 to[u].push_back(v); 81 to[v].push_back(u); 82 } 83 for(int i=1;i<=n;i++){bfs(i);} 84 scanf("%d",&w); 85 for(int i=1;i<=w;i++) 86 scanf("%I64d%I64d%I64d",&st[i].c,&st[i].k,&st[i].p); 87 sort(st+1,st+1+w,cmp); 88 scanf("%d",&q); 89 while(q--){ 90 scanf("%d%d%d",&g,&r,&a); 91 int ll=0,rr=n,mid,ans=-1; 92 while(ll<=rr){ 93 mid=(ll+rr)>>1; 94 if(check(g,mid,r,a))ans=mid,rr=mid-1; 95 else ll=mid+1; 96 } 97 printf("%d ",ans); 98 } 99 return 0; 100 }
D.running over the bridge
有n座桥,每座桥si长,人走在上面后ti秒就倒,人的速度是0.5,有无限瓶能量饮料,喝一瓶可以在r秒内变成1速度,但是只能在整数时点喝,且不能在效果持续时喝(T时喝,T+ti时可以再喝,中间不可以喝)
xjb贪心,把喝饮料的开始时间尽量延迟,然后二分推
1 /************************************************ 2 *Author* : Ray(siludose) 3 *Created Time* : 2016年10月28日 星期五 09时48分11秒 4 **Problem** : cf730d.cpp 5 **Analyse** : 6 **Get** : 7 **Code** : 8 *********************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 #include <vector> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <string> 19 #include <cmath> 20 #include <cstdlib> 21 #include <ctime> 22 #include <stack> 23 using namespace std; 24 typedef pair<int, int> pii; 25 typedef __int64 ll; 26 typedef unsigned long long ull; 27 #define pri(a) printf("%d ",(a)) 28 #define xx first 29 #define yy second 30 const int mod = int(1e9) + 7, INF = 0x3f3f3f3f; 31 const int maxn = 2e5 + 13; 32 33 ll n,r; 34 ll l[maxn],t[maxn]; 35 queue<ll>q; 36 int main(void) 37 { 38 scanf("%I64d%I64d",&n,&r); 39 for(int i=1;i<=n;i++)scanf("%I64d",&l[i]); 40 for(int i=1;i<=n;i++)scanf("%I64d",&t[i]); 41 ll mt=0,ans=0,tt=0; 42 for(int i=1;i<=n;i++){ 43 if(l[i]>t[i]){printf("-1 ");return 0;} 44 if(2*l[i]<=t[i]){ 45 if(mt)tt+=mt>l[i]?l[i]:l[i]*2-mt,mt=mt>l[i]?mt-l[i]:0; 46 else tt+=l[i]*2; 47 continue; 48 }//don't have to jiasu 49 ll te=2*l[i]-t[i];//need to add speed. mt:the add rest 50 if(mt>=te){tt+=mt>l[i]?l[i]:(l[i]*2-mt);mt=mt>l[i]?mt-l[i]:0;continue;} 51 else if(mt!=0){tt+=mt;l[i]-=mt;t[i]-=mt;i--;mt=0;continue;} 52 else{ 53 ll a=te/r,b=te%r; 54 ans+=b==0?a:a+1; 55 if(ans<=100000) 56 for(ll j=tt+(l[i]-te)*2;j<tt+t[i];j+=r)q.push(j); 57 tt+=l[i]*2-te; 58 mt=b==0?0:(a+1)*r-te; 59 } 60 } 61 printf("%I64d ",ans);if(ans>100000)return 0; 62 while(!q.empty()){printf("%I64d ",q.front());q.pop();} 63 return 0; 64 }
E.award ceremony
在另外一个世界,icpc比赛的排序方式是:分数高的排位高,其次id值小的排位高。并且,最后1小时也会封榜,最后才揭晓真正排名,一个个队改变排名
问:如何安排各个队的分数改变顺序,使排名变化次数较多?(点数最多100)
起初我想用树状数组的方法,就是把2组状态集合到一起排序,然后每次贪心移动。
但是一直都没法让数据与我的想法对接
看到一些人的思路才“na ru ho do”每对点的影响都要算和,对答案贡献:点对间如果没有交叉是0,包含关系或交叉但是增减方向相反的肯定是1,交叉并且增减方向相同就是2
这样就轻易出解了。。。白纠结那么久
1 /************************************************ 2 *Author* : Ray(siludose) 3 *Created Time* : 2016年10月29日 星期六 10时49分45秒 4 **Problem** : cf730e.cpp 5 **Analyse** : 6 **Get** : 7 **Code** : 8 *********************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 #include <vector> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <string> 19 #include <cmath> 20 #include <cstdlib> 21 #include <ctime> 22 #include <stack> 23 using namespace std; 24 typedef pair<int, int> pii; 25 typedef long long ll; 26 typedef unsigned long long ull; 27 #define pri(a) printf("%d ",(a)) 28 #define xx first 29 #define yy second 30 const int mod = int(1e9) + 7, INF = 0x3f3f3f3f; 31 const int maxn = 200; 32 33 struct node{ 34 int num,ran,add; 35 bool operator < (const node &a)const{ 36 return num>a.num||(num==a.num&&ran<a.ran); 37 } 38 }a[maxn]; 39 int ok(int i,int j){ 40 node x=a[i],y=a[j],xx=x,yy=y; 41 xx.num+=x.add,yy.num+=y.add; 42 if(x<y&&yy<xx)return 1; 43 if(y<x&&xx<yy)return 1; 44 if(x<y&&y<xx&&xx<yy)return 2; 45 if(y<x&&x<yy&&yy<xx)return 2; 46 if(yy<xx&&xx<y&&y<x)return 2; 47 if(xx<yy&&yy<x&&x<y)return 2; 48 return 0; 49 } 50 int main(void) 51 { 52 int n,ans=0; 53 scanf("%d",&n); 54 for(int i=1;i<=n;i++)scanf("%d %d",&a[i].num,&a[i].add),a[i].ran=i; 55 for(int i=1;i<=n;i++){ 56 for(int j=i+1;j<=n;j++){ 57 ans+=ok(i,j); 58 } 59 } 60 printf("%d ",ans); 61 return 0; 62 }
题意:n天在饭馆吃饭,第i天花费cost(i),奖券最多使用floor(cost(i)/2),使用奖券p点,可以省p元,得到floor((a(i)-p)/10)点奖券,问如何使用可以最大化优惠
之前一直想用o(nlogn)贪心做,从左到右,发现思路太过复杂,把优惠尽量往后推,但是发现如果用除法得到优惠点数,思路比较麻烦
右边的不仅要加1点,要是剩余奖券积了10张还要再处理
剩余的还要再往左遍历一遍,把最大的零头用奖券处理
后来发现不用这么麻烦,消费请求组什么的不用看做1个数字,而是多个数据放到列表来处理
遍历顺序也不正着来,反着来的话,可以把优惠尽量往后推
也不用考虑剩余奖券的问题,因为昨天不能用今天可以用的奖券,直接无视,只保存消费请求
#include<cstdio> #include<vector> #include<algorithm> using namespace std; int n, coin, money; int a[5555]; int expire[5555]; vector<int> fre, locked[11]; int ans[5555]; void add_fre(int amount, int id) { for(int i=0;i<amount;i++) fre.push_back(id); } void try_spend_fre(int &amount) { while(amount && fre.size()) { ans[fre.back()] ++; amount --; fre.pop_back(); } } void try_spend(int &amount) { try_spend_fre(amount); for(int i=10;i>0 && amount;i--) while(amount && locked[i].size()) { amount --; int id = locked[i].back(); locked[i].pop_back(); add_fre(i, id); try_spend_fre(amount); } } int main() { scanf("%d%d", &n, &coin); money = 0; for(int i=1;i<=n;i++) { scanf("%d", &a[i]); // 先佯装全额付账,攒冥币.. int today_coin = a[i] / 10; expire[i+1] = today_coin; // 今天挣了多少个币,这些币反着for时第i+1天不用就没得用了 money += a[i]; } for(int i=n;i>0;i--) { int today_discount = a[i]/2; // 大if出没注意!!如果第i+1天有剩余的钱,今天虽然没法花,但是相应的锁也不必加了。 // 这个情况包含了最后一天花不出去的情况。 int lock_fre = expire[i+1]; // 付了也没法多得到冥币的零头,一开始就没锁定 int today_fre = min(a[i]%10, today_discount); add_fre(today_fre, i); today_discount -= today_fre; // 需要花1个冥币才能解锁的部分 for(int j=today_discount / 10; j>0; j--) if (lock_fre) { lock_fre --; add_fre(10, i); } else locked[10].push_back(i); today_discount %= 10; if (today_discount) { if (lock_fre) add_fre(today_discount, i); else locked[today_discount].push_back(i); } try_spend(expire[i]); // 尝试把今天过期的币用掉 } try_spend(coin); for(int i=1;i<=n;i++) money -= ans[i]; printf("%d ", money); for(int i=1;i<=n;i++) printf("%d%c", ans[i], i<n ? ' ' : ' '); return 0; }
顺带来一发未完成的
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> #include <cstring> #include <fstream> using namespace std; typedef __int64 ll; const int N=5030; int min(int a,int b){return a<b?a:b;} int a[N],b[N]; int main() { int n,bon,i,sum=0; scanf("%d%d",&n,&bon); for(i=0;i<n;i++) { scanf("%d",a+i); int lim=a[i]/2; int m10=(lim-a[i]%10)/10;//the most bonus*10 if(bon<a[i]%10)b[i]=0; else b[i]=a[i]%10+min(m10,(bon-a[i]%10)/10)*10; bon-=b[i]; if(i!=0) { while(b[i-1]>=10 && lim>=b[i]+10) { b[i-1]-=10; b[i]+=10; bon++; if(bon==10 && lim>=b[i]-10) bon-=10,b[i]+=10; } } bon+=(a[i]-b[i])/10; } int proc=bon; bon-=(a[n-1]-b[n-1])/10; int min1=bon,spe=min(bon,a[n-1]/2-a[n-1]+b[n-1]); b[n-1]+=spe; bon-=spe; spe=0; for(i=n-2;i>=0;i--) { bon+= } for(i=0;i<n;i++)sum+=a[i]-b[i]; printf("%d ",sum); for(i=0;i<n;i++)printf("%d%c",b[i],i!=n-1?' ':' '); return 0; }
G. Car Repair Shop
#pragma warning(disable:4996) #include<iostream> #include<cstdio> #include <algorithm> #include <string.h> #include <queue> #include <vector> #include <stack> #include <set> #include <list> using namespace std; const int maxn = 100100; #define ll long long int main() { int n; scanf("%d", &n); int s[205], d[205]; for (int i = 0;i < n;i++) { scanf("%d%d", &s[i], &d[i]); bool change = false; for (int j = 0;j < i;j++) { if (!((s[i] + d[i] <= s[j]) || (s[i] >= s[j] + d[j]))) { if (change == false) { s[i] = 1; j = -1; change = true; } else { s[i] = s[j] + d[j]; j = -1; } } } printf("%d %d ", s[i], s[i] + d[i] - 1); } return 0; }
H.Delete Them
1 /************************************************ 2 *Author* : Ray(siludose) 3 *Created Time* : 2016年10月24日 星期一 16时41分41秒 4 **Problem** : cf730h.cpp 5 **Analyse** : 6 **Get** : 7 **Code** : 8 *********************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 #include <vector> 15 #include <queue> 16 #include <set> 17 #include <map> 18 #include <string> 19 #include <cmath> 20 #include <cstdlib> 21 #include <ctime> 22 #include <stack> 23 using namespace std; 24 typedef pair<int, int> pii; 25 typedef long long ll; 26 typedef unsigned long long ull; 27 #define pri(a) printf("%d ",(a)) 28 #define xx first 29 #define yy second 30 const int mod = int(1e9) + 7, INF = 0x3f3f3f3f; 31 const int maxn = 110; 32 33 int n,m; 34 char s[maxn][maxn]; 35 char t[maxn]; 36 int nu[maxn],len[maxn]; 37 bool vis[maxn]; 38 bool match(int v) 39 { 40 int c=strlen(s[v]); 41 if(c!=len[0])return 0; 42 for(int i=0;i<len[0];i++){ 43 if(t[i]!='?'&&t[i]!=s[v][i])return 0; 44 } 45 return 1; 46 } 47 int main(void) 48 { 49 scanf("%d%d",&n,&m); 50 for(int i=0;i<n;i++)scanf("%s",s[i]); 51 for(int i=0;i<m;i++)scanf("%d",&nu[i]),nu[i]--,vis[nu[i]]=true; 52 for(int i=0;i<m;i++){ 53 len[i]=strlen(s[nu[i]]); 54 if(len[i]!=len[0]){ 55 printf("No ");return 0; 56 } 57 } 58 for(int i=0;i<len[0];i++){ 59 t[i]=s[nu[0]][i]; 60 for(int j=0;j<m;j++){ 61 if(t[i]!=s[nu[j]][i])t[i]='?'; 62 } 63 } 64 for(int i=0;i<n;i++) 65 if(!vis[i]) 66 if(match(i)){ 67 printf("No ");return 0; 68 } 69 t[len[0]]='