- 过题情况
- 第一题 100%
- 第二题 100%
- 第三题 100%
- 第四题 20%
第一题:
小模拟
#include<bits/stdc++.h>
using namespace std;
const int maxn=200;
int a[maxn];
int main(){
int k,n;
scanf("%d%d",&k,&n);
int flag=0, step=0, ret=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(step==k)flag=1;
step+=a[i];
if(step>k){
step=2*k-step;
ret+=1;
}
}
if(flag==1)printf("paradox\n");
else printf("%d %d\n", k-step, ret);
return 0;
}
第二题
暴力模拟向左/右转1-3次,向上/下转1-3次,即六种情况,遍历六次就能得到所有的情况,取字典序最小的作为统一答案进行统计。
#include<bits/stdc++.h>
using namespace std;
map<int,int>q;
int a[10];
int num=1e9;
void dfs(int b[], int step){
if(step==6)return;
int tmp=0;
for(int i=1;i<=6;i++)
tmp=tmp*10+b[i];
num=min(num,tmp);
for(int i=1;i<=6;i++){
int c[10];
if(i==1){
c[1]=b[1];c[2]=b[2];c[3]=b[5];c[4]=b[6];c[5]=b[4];c[6]=b[3];
}
else if(i==2){
c[1]=b[1];c[2]=b[2];c[3]=b[4];c[4]=b[3];c[5]=b[6];c[6]=b[5];
}
else if(i==3){
c[1]=b[1];c[2]=b[2];c[3]=b[6];c[4]=b[5];c[5]=b[3];c[6]=b[4];
}
else if(i==4){
c[1]=b[6];c[2]=b[5];c[3]=b[3];c[4]=b[4];c[5]=b[1];c[6]=b[2];
}
else if(i==5){
c[1]=b[2];c[2]=b[1];c[3]=b[3];c[4]=b[4];c[5]=b[6];c[6]=b[5];
}
else if(i==6){
c[1]=b[5];c[2]=b[6];c[3]=b[3];c[4]=b[4];c[5]=b[2];c[6]=b[1];
}
dfs(c, step+1);
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
for(int j=1;j<=6;j++)
scanf("%d",&a[j]);
num=1e9;
dfs(a, 0);
q[num]+=1;
}
map<int, int>::iterator it;
priority_queue<int>que;
for(it=q.begin();it!=q.end();it++){
que.push(it->second);
}
printf("%d\n%d",que.size(), que.top());
que.pop();
while(!que.empty()){
printf(" %d",que.top());
que.pop();
}
printf("\n");
return 0;
}
第三题
二分完求区间最小值,这里用的树状数组,注意单个点的情况。
好吧,我第三题当时没好好想,其实就是二分后求一个后缀的最小值,不用树状数组求区间最值,当时没想清楚。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+200;
int n,m,t;
struct node{
int x,y;
}a[maxn],b[maxn];
bool cmp(node c,node d){
return c.x<d.x;
}
int c[maxn],d[maxn];
int lowbit(int x){
return x&(-x);
}
void update(int x){
while(x<=n){
c[x]=a[x].y;
int lx=lowbit(x);
for(int i=1;i<lx;i<<=1)
c[x]=min(c[x],c[x-i]);
x+=lowbit(x);
}
}
int query(int x,int y){
int ans=1e9;
while(y>=x){
ans=min(a[y].y, ans);
y--;
for(;y-lowbit(y)>=x;y-=lowbit(y))
ans=min(c[y],ans);
}
return ans;
}
int main(){
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].y,&a[i].x);
for(int i=1;i<=m;i++)
scanf("%d%d",&b[i].y,&b[i].x);
sort(a+1,a+n+1,cmp);
sort(b+1,b+m+1,cmp);
if(a[n].x+b[m].x<t){
printf("-1\n");
return 0;
}
int ans=1e9;
for(int i=1;i<=n;i++)
{
update(i);
d[i]=a[i].x;
if(a[i].x>=t)
ans=min(a[i].y, ans);
//printf("%d\n", d[i]);
}
for(int i=1;i<=m;i++){
if(b[i].x>=t){
ans=min(ans, b[i].y);
}
else {
int pos=lower_bound(d+1,d+1+n,t-b[i].x)-d;
ans=min(ans, b[i].y+query(pos, n));
}
}
if(t==0)printf("0\n");
else printf("%d\n",ans);
return 0;
}
第四题
还有半小时不太想写了,10min暴力骗分20%。
看到牛客有大牛用插头dp搞得
#include<bits/stdc++.h>
using namespace std;
const int maxn=10;
const int mod=1e9+9;
char c[maxn][maxn];
int a[maxn][maxn];
int ans=0;
vector<pair<int,int> >q;
int dx[4]={-1,0,0,1},dy[4]={0,-1,1,0};
bool check(){
for(int k=0;k<(int)q.size();k++){
int i=q[k].first, j=q[k].second;
int flag=0;
for(int z=0;z<4;z++){
int x=i+dx[z],y=j+dy[z];
if(x<0||x>5||y<0||y>5||c[x][y]=='*')continue;
if(a[i][j]==a[x][y])flag=1;
}
if(flag==1)return 0;
}
return 1;
}
void dfs(int pos){
if(pos==(int)q.size()){
if(check())
ans++;
return ;
}
for(int i=1;i<=6;i++){
a[q[pos].first][q[pos].second]=i;
dfs(pos+1);
}
}
int main(){
for(int i=0;i<6;i++)
{
scanf("%s",c[i]);
for(int j=0;j<6;j++)
if(c[i][j]=='#')q.push_back(make_pair(i, j));
}
dfs(0);
printf("%d\n",ans);
}