A. Contest for Robots(模拟+贪心)
计算第一家公司可以跑第二家公司不能跑的关卡。如果是0答案为-1;否则如果第一家可以跑的总关卡数目比第二家多,答案为1,如果小于等于第二家答案为 第二家+1-第一家/第一家可以二第二家不可以 向上取正。
#include<cstdio>
#include<iostream>
using namespace std;
int p1[102];
int p2[102];
int n;
int s1;
int s2;
int d;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&p1[i]);
s1+=p1[i];
}
for(int i=1;i<=n;i++){
scanf("%d",&p2[i]);
s2+=p2[i];
}
if(s2<s1){
printf("1\n");
}else{
for(int i=1;i<=n;i++){
if(p1[i]==1&&p2[i]!=1){
d++;
}
}
if(d==0){
printf("-1");
}else{
int ans=s2+d-s1+1;
if(ans%d==0)
printf("%d\n",ans/d);
else printf("%d\n",(ans/d)+1);
}
}
return 0;
}
B. Journey Planning(桶)
分组然后找最大,分组规则:按c[i]-i的值分组,相同的可以相通;用桶记录每一组的个数;分组计算。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int a[200005];
int buk[800005];
long long cnt[800005];
long long ans;
const int maxn=200005;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
a[i]-=i;
buk[maxn+a[i]]++;
}
for(int i=1;i<=n;i++){
cnt[maxn+a[i]]+=i;
}
for(int i=0;i<=800005;i++){
ans=max(ans,cnt[i]+(long long)buk[i]*(i-maxn));
}
printf("%lld\n",ans);
return 0;
}
C. Remove Adjacent(链表+贪心)
实现字符删除用链表,删除后面的字母对较小的字母没有影响所以选择贪心。
#include<cstdio>
#include<iostream>
using namespace std;
struct node{
int ch;
node * pre;
node * next;
node(){
}
};
node * beginn=new node();
node * endd=new node();
long long ans;
long long n;
void insert(node * p,int x){
endd=new node();
p->next=endd;
p->ch=x;
endd->next=NULL;
endd->pre=p;
endd->ch=-1;
}
void del(node * p){
p->pre->next=p->next;
p->next->pre=p->pre;
delete p;
}
void opr(int u){
node *i=beginn->next;
while(i!=endd){
if(i->ch==u&&((i->pre->ch==i->ch-1)||(i->next->ch==i->ch-1))){
ans++;
node * u=i;
i=i->next;
del(u);
}else{
i=i->next;
}
}
}
void print(){
node * i=beginn->next;
while(i!=endd){
printf("%d ",i->ch);
i=i->next;
}
printf("\n");
}
int main(){
cin>>n;
beginn->next=endd;
endd->pre=beginn;
beginn->ch=-1;
endd->ch=-1;
for(int i=1;i<=n;i++){
char c;
cin>>c;
insert(endd,c-'a'+1);
}
for(int i=26;i>=1;i--){
for(int j=1;j<=n;j++)
opr(i);
//print();
}
cout<<ans<<endl;
return 0;
}
D. Navigation System(最短路)
反向建图,bfs求最短路,并记录不同从目的地到i最短路dis[i]的数量cnt[i]。计算固定路径上,一个节点与前一个节点的最短路看看是否满足的dis[i]=dis[i-1]+1:如果满足并且cnt[i]>1maxm++;否则maxm++,minm++;
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn=200005;
struct node{
int i;
int d;
node(int a,int b):i(a),d(b){
}
node(){
}
};
struct Edge{
int from;
int to;
Edge(){
}
Edge(int a,int b):from(a),to(b){
}
}Edges[maxn];
vector<int>G[maxn];
int t;
void addEdge(int a,int b){
Edges[t]=Edge(a,b);
G[a].push_back(t);
t++;
}
int vis[maxn];
int dis[maxn];
int cnt[maxn];
int n,m;
int k;
int p[maxn];
void bfs(int u){
queue<node>Q;
while(!Q.empty())Q.pop();
Q.push(node(u,0));dis[u]=0; vis[u]=1;
while(!Q.empty()){
node &o=Q.front();Q.pop();
for(int j=0;j<G[o.i].size();j++){
if(!vis[Edges[G[o.i][j]].to]){
dis[Edges[G[o.i][j]].to]=o.d+1;
Q.push(node(Edges[G[o.i][j]].to,o.d+1));
cnt[Edges[G[o.i][j]].to]=1;
vis[Edges[G[o.i][j]].to]=1;
}else{
if(o.d+1==dis[Edges[G[o.i][j]].to])cnt[Edges[G[o.i][j]].to]++;
}
}
}
}
long long maxm,minm;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
addEdge(b,a);
}
scanf("%d",&k);
for(int i=1;i<=k;i++){
scanf("%d",&p[i]);
}
bfs(p[k]);
/*for(int i=1;i<=n;i++){
printf("%d ",dis[i]);
}
for(int i=1;i<=n;i++){
printf("%d ",cnt[i]);
}*/
for(int i=1;i<=k;i++){
if(i>1){
if(dis[p[i-1]]!=1+dis[p[i]]){
maxm++;
minm++;
}else{
if(cnt[p[i-1]]>1){
maxm++;
}
}
}
}
cout<<minm<<" "<<maxm<<endl;
return 0;
}
待补:
D. Navigation System(线段树or分块)
E. World of Darkraft: Battle for Azathoth(字符串哈希+线段树)