昨天的笔试,做得挺难受的,当时正在搬寝室,很吵,然后保洁阿姨来打扫寝室卫生…
2.5小时,4道编程题,每道题100分。 1, 0.2 0 0.1 ,第2题应该就是模拟,说我TLE,第三题bfs,说段错误,不知道map哪里来的段错误…, 第四题就5分钟了,想到了思路,细节除了点问题,敲完就交了,剩下几秒钟结束,过了10%,j++写成了i++…
模拟一个自动贩卖机。贩卖机有n个货物口,每个货口初始都放了无限多的相同的货物,货物的单价为a[i], 每个人通过手机扫码可以打开贩卖机的门,拿东西,然后关上门之后,贩卖机会自动扣费。现在让你实现这个计费功能。
每个人可以从x号货物口拿一个货物到左手或者右手上,记为take left x 或者 take right x。可以把左手或者右手的货物放到y号货物口,记为return left y 或者 return right y。还可以把左手或者右手上拿的货物装进背包里。记为keep left 或 keep right。
货物口的货物满足后进先出的原则。T组输入,T<=100, 每组输入第一行一个K(K<=100),代表这个人的操作的个数,下面是K行,每行一个命令,命令有如下:
take left x(数字)
take right x(数字)
return left x
return right x
keep left
keep right
每个人输出一行,输出他要付的钱。
%100 AC
#include
using namespace std;
const int N = 200;
stack<int> st[N];
int price[N];
char hand[100],op[100];
int main(void) {
int n,m,k,id;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) {
scanf("%d",price+i);
for(int j=1;j<=10001;++j)
st[i].push(price[i]);
}
for(int i=1;i<=m;++i) {
scanf("%d",&k);
int man[2] = {0};
int hands = -1;
man[0] = man[1] = 0;
int tot = 0;
while(k--) {
scanf("%s%s",hand,op);
if(strcmp("keep",op)!=0) scanf("%d",&id);
if(strcmp(hand,"left")==0) hands = 0;
else hands = 1;
if(strcmp(op,"take")==0) {
man[hands] = st[id].top();
st[id].pop();
}
else if(strcmp(op,"return")==0) {
st[id].push(man[hands]);
man[hands] = -1;
}
else {
tot += man[hands];
man[hands] = -1;
}
}
if(man[0]!=-1) tot+=man[0];
if(man[1]!=-1) tot+=man[1];
printf("%d\n",tot);
}
return 0;
}
一个h*w的显示器,要在上面显示一个图像平移的动画。图像大小为q*p。(1<=p,q,h,w<=100)。 在显示器上面显示背景,然后图像要覆盖背景。图像开始的时候左上角的位置在(stx,sty)(可能是负数)每次图像向右移动dy,向左移动dx,屏幕的每个单元格,如果和上次的字符不一样,就需要刷新。问最少刷新几次?
T组输入,保证dx和dy不同时为0。
1
4 4
....
....
....
....
3 3
.o.
/|\
./\
0 0 1 1
26
开始屏幕只有背景
....
....
....
....
第一次的图像:
|\..
/\..
....
....
第二次的图像:
.o..
/|\.
./\.
....
第三次的图像
....
..o.
./|\
../\
第四次的图像
....
....
...o
../|
第五次就出去了
....
....
....
....
思路就是按题意模拟,不到为什么TLE, 只过了20%的数据,具体做法见代码
#include
using namespace std;
const int N = 200;
char a[N][N]; //存背景
char b[N][N]; //存动画
char pre[N][N]; //存上一次屏幕的内容
char c[N][N]; //存当前品屏幕内容
int main(void) {
int T,w,h,p,q,dx,dy,stx,sty;
scanf("%d",&T); //T组输入
while(T--) {
scanf("%d%d",&w,&h);
for(int i=1;i<=h;++i) { //输入背景
scanf("%s",a[i]+1);
}
scanf("%d%d",&p,&q);
for(int i=1;i<=q;++i) { //输入图像
scanf("%s",b[i]+1);
}
scanf("%d%d%d%d",&stx,&sty,&dy,&dx);
int x1 = stx, x2 = stx+q-1, y1 = sty, y2 = sty+p-1;
bool existx = true,existy = true;
if((x1>h&&dx>=0)||(x2<1&&dx<=0)) existx = false;
if((y1>w&&dy>=0)||(y2<1&&dy<=0)) existy = false;
if(!existx&&!existy) { //如果图像根本不会在屏幕上出现,直接输出0
puts("0");continue;
}
int flag = 0;
int ans = 0;
for(int i=1;i<=h;++i)
for(int j=1;j<=w;++j)
pre[i][j] = a[i][j];
int nowx1 = stx, nowy1=sty; //记录图像左上角的结点
while(1) { //模拟
bool in = false;
int xx1 = nowx1,xx2 = nowx1+q-1;
int yy1 = nowy1,yy2 = nowy1+p-1;
if((xx1>h||xx2<1)||(yy1>w||yy2<1)) in = false;
else in = true;
if(in) flag = true;
else{ //如果这次没在拼命上出现,之前出现过了,说明已经远离屏幕了
if(flag) break;
else {
nowx1 += dx;
nowy1 += dy;
continue;
}
}
for(int i=1;i<=h;++i) { //先画背景
for(int j=1;j<=w;++j)
c[i][j] = a[i][j];
}
for(int i=0;i<q;++i) { //再在背景上画图
for(int j=0;j<p;++j) {
if(i+nowx1>=1&&i+nowx1<=h&&j+nowy1>=1&&j+nowy1<=w) {
c[i+nowx1][j+nowy1] = b[i+1][j+1];
}
}
}
int cnt = 0;
for(int i=1;i<=h;++i) {
for(int j=1;j<=w;++j) { //对比这次和上一次的不同。计数
if(c[i][j]!=pre[i][j]) ++cnt;
pre[i][j] = c[i][j];
}
}
ans += cnt; //累计答案
nowx1+=dx;
nowy1+=dy;
}
printf("%d\n",ans);
}
return 0;
}
有一个迷宫,你不知道整体情况,只可以试探。用0,1,2,3分别代表上,下,左,右。每次试探,如果可以走,返回1,并且走到试探的位置,如果不可以走,说明有障碍物或者是边界,呆在原地。一共试探了n次,n<=1000,000。保证最后一次试探走到了终点,返回为1。问你从约起点到终点的最短路径长度是多少?
T组输入,T<=100, 每组输入第一行为n,代表试探的次数,n<=1E6。每组输出起点到终点的最少步数。
3
10
0 1
0 -1
1 1
1 1
1 -1
0 1
2 1
2 -1
3 1
3 1
2
3 1
3 1
8
0 1
0 1
3 1
3 1
1 1
1 1
2 1
0 1
1
2
2
题目隐含的意思是,没出现的位置都不能走,有障碍的位置也不能走,只能走到已经试探成功的,并且和当前位置相邻的位置。
一开始以为只有走过的路才能走,就单纯地把二维坐标 映射成一位的id, 建立邻接表BFS, 没有考虑到位置的相邻关系,结果样例3就输出了8。
然后把所有能走的点都标记,然后从起点开始,上下左右bfs。不知道为什么,说段错误,0%,很奇怪,有大佬可以看看代码吗?
#include
using namespace std;
const int N = 1e6+100;
int dx[] = {-1,1,0,0};
int dy[] ={0,0,-1,1};
map<pair<int,int>,int>mp; //每个坐标的编号
vector<pair<int,int> > v; //编号->坐标 ,存坐标
map<pair<int,int>,int> no; //存哪些点不能走(其实没出现过的就不能走)
int cnt = 0;
struct P{
pair<int,int> pos;
int step;
P(){}
P(pair<int,int>p,int st) {
pos = p;step = st;
}
};
map<pair<int,int>,int> vis;
int bfs() {
if(cnt-1==0) return 0;
vis.clear();
queue<P> Q; //first:id, second step
pair<int,int> st(0,0);
pair<int,int> ed = v[cnt-1];
Q.push(P(st,0));
vis[st] = 1;
while(!Q.empty()) {
pair<int,int> now = Q.front().pos;
int step = Q.front().step;
Q.pop();
int x = now.first, y = now.second;
for(int i=0;i<4;++i) {
int xx = x+dx[i];
int yy = y+dy[i];
pair<int,int> to(xx,yy);
if(no.find(to)!=no.end()||mp.find(to)==mp.end()) continue;
if(to==ed) return step+1;
if(vis.find(to)!=vis.end()) continue;
vis[to] = 1;
Q.push(P(to,step+1));
}
}
return -1;
}
int main(void) {
freopen("inC.txt","r",stdin);
int T,n;
scanf("%d",&T);
while(T--) {
v.clear();
mp.clear();
no.clear();
scanf("%d",&n);
cnt = 0;
int x = 0,y = 0;
pair<int,int> pr(0,0);
v.push_back(pr);
mp[pr] = cnt++;
int op,res;
while(n--) {
scanf("%d%d",&op,&res);
if(res==-1) {
no[make_pair(x+dx[op],y+dy[op])] = 1;
continue;
}
int xx = x+dx[op];
int yy = y+dy[op];
pr.first = xx; pr.second = yy;
auto it = mp.find(pr);
if(it==mp.end()) {
v.push_back(pr);
mp[pr] = cnt++;
}
x = xx; y = yy;
}
printf("%d\n",bfs());
}
return 0;
}
给一个序列,你需要排序,排序之后,要满足a[i] * a[i+1] <= a[i+1] * a[i+2]
如 1,2,3,4
输出1,2,3,4
就剩下10分钟了,想到了正确思路,但是细节没处理好,j++写成了i++。思路是这样的,正数从大到小排,负数从小到大排,然后正负数交替。如果负数没了,就从小到大输出剩下的正数,如果正数没了,就从大到小输出负数。
但是注意,正数或者负数没了,就立刻break。
#include
using namespace std;
int a[1000000];
vector<int> v1,v2;
int main(void) {
int n;
cin>>n;
int x;
for(int i=1;i<=n;++i) {
scanf("%d",&x);
if(x>=0) v2.push_back(x);
else v1.push_back(x);
}
sort(v1.begin(),v1.end());
sort(v2.begin(),v2.end(),[](int a,int b){return a>b;
});
int len1 = v1.size(),len2 = v2.size();
int i = 0, j = 0;
// while(i
// printf("%d %d ",v1[i++],v2[j++]);
// }
while(i<len1&&j<len2) {
printf("%d ",v1[i++]);
if(i==len1) break;
printf("%d ",v2[j++]);
if(j==len2) break;
}
if(i<len1) {
sort(v1.begin()+i,v1.end(),[](int a,int b){return a>b;
});
for(int ii=i;ii<len1;++ii) cout<<v1[ii]<<" ";
cout<<endl;return 0;
}
else {
sort(v2.begin()+j,v2.end());
for(int jj=j;jj<len2;++jj) cout<<v2[jj]<<" ";cout<<endl;
}
return 0;
}
应该改了之后就没问题了
牛客上一个300分的帖子