今天做的是11年day1的真题
- 由于我平时比较懒所以真题真的不怎么做(小声bb,千万不能被教练发现
- 但确实day1的题比较简单。
第一题——铺地毯(carpet)
- 这道真的很水的,数据量也没有多少(只有一万)
- 首先小学生都知道这道题不可能用每个点的模拟更新来做
- 那干脆直接把这个图存下来,再单点查询就好了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
void fff(){
freopen("carpet.in","r",stdin);
freopen("carpet.out","w",stdout);
}
const int MAXN=10100;
struct node{
int x1,x2,y1,y2;
}a[MAXN];
int n,goal_x,goal_y,ans;
bool check(int x){
if(a[x].x1>goal_x||a[x].x2<goal_x) return false;
if(a[x].y1>goal_y||a[x].y2<goal_y) return false;
return true;
}
int main(){
fff();
ans=-1;
scanf("%d",&n);
for (int i=1;i<=n;i++){
int g,k;
scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&g,&k);
a[i].x2=a[i].x1+g;
a[i].y2=a[i].y1+k;
}
scanf("%d%d",&goal_x,&goal_y);
for (int i=1;i<=n;i++){
if(check(i)) ans=i;
}
printf("%d",ans);
}
第二题——选择客栈(hotel)
- 这是一道类似于dp的题,问你两个相同颜色之间的点(包含)是否有值小于等于目标值
- 讲道理这道题也是很水的。
- 打一把st算出两点之间是否有合法值
- 读入的时候把相同颜色的存下来然后枚举查询
- 然后就AC
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
using namespace std;
void fff(){
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
}
const int MAXN=200100;
vector <int> color[51];
struct node{
int color_num,prize;
}a[MAXN];
int n,k,p;
int m[MAXN][21];
void st(){
memset(m,0,sizeof(m));
for (int i=1;i<=n;i++) if(a[i].prize<=p) m[i][0]=1;
for (int j=1;(1<<j)<=n;j++){
for (int i=1;i+(1<<j)-1<=n;i++){
m[i][j]=m[i][j-1]+m[i+(1<<(j-1))][j-1];
}
}
}
int Query(int x,int y){
if(x>y) swap(x,y);
int k=(log(y-x+1)/log(2));
int temp=0;
return (m[x][k]+m[y-(1<<k)+1][k]);
}
int main(){
int ans=0;
scanf("%d%d%d",&n,&k,&p);
for (int i=1;i<=n;i++){
scanf("%d%d",&a[i].color_num,&a[i].prize);
color[a[i].color_num].push_back(i);
}
st();
for (int i=0;i<=k;i++){
int s=color[i].size();
for (int j=0;j<s-1;j++){
int t=j+1;
while (true){
int tt=color[i][j],b=color[i][t];
if(Query(tt,b)>0) break;
t++;
}
ans+=(s-t);
}
}
cout<<ans;
}
第三题——Mayan游戏(mayan)
- 一看这个数据量我就知道这个是深搜题,不过状态刚开始不知道怎么存,就有点尴尬(只靠输出-1打了两个点)
- 无脑深搜,外存状态吧(具体怎么存就看代码吧)。再剪下枝就可以过了。
- 剪枝有以下几个方面去考虑:
- 首先如果对于一个点左边有值那他就不用再往左搜索(之前就做过往右了,换一下效果一样,唯一不同就是TEL…)
- 第二,如果存在一个状态有数值只剩下两个就一定消不掉(但这个我其实没有判因为省不了多少时间。)
- 第三两个一样的块是不会交换的(效果真的真的一样。)
- 一百行的深搜真的很少打,要好好学习代码实现了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
using namespace std;
void fff(){
freopen("mayan.in","r",stdin);
freopen("mayan.out","w",stdout);
}
const int MAXN=99999;
int n;
int map[7][5][7];
int ansx[10],ansy[10],ansg[10];
bool visited[5][7];
void fall(int step){
for (int i=0;i<5;i++){
int sz=0;
for (int j=0;j<7;j++){
if(map[step][i][j]) map[step][i][sz++]=map[step][i][j];
}
while (sz<7) map[step][i][sz++]=0;
}
}
void mv(int step){
int tim=0;
bool cg=true;
while (cg){
cg=false;
fall(step);
for (int i=0;i<5;i++)
for (int j=0;j<7;j++)
if(map[step][i][j]){
if (i<3){
if(map[step][i][j]==map[step][i+1][j]&&map[step][i][j]==map[step][i+2][j]){
cg=visited[i][j]=visited[i+1][j]=visited[i+2][j]=true;
}
}
if (j<5){
if(map[step][i][j]==map[step][i][j+1]&&map[step][i][j]==map[step][i][j+2]){
cg=visited[i][j]=visited[i][j+1]=visited[i][j+2]=true;
}
}
}
for (int i=0;i<5;i++)
for (int j=0;j<7;j++){
if(visited[i][j]) map[step][i][j]=visited[i][j]=0;
}
}
}
bool dfs(int step){
for (int i=0;i<5;i++){
for (int j=0;j<7;j++){
map[step][i][j]=map[step-1][i][j];
}
}
mv(step);
if(step==n+1){
for (int i=0;i<5;i++) if(map[step][i][0]) return false;
return true;
}
for (int i=0;i<5;i++)
for (int j=0;j<7;j++){
if(map[step][i][j]){
if(i<4&&map[step][i][j]!=map[step][i+1][j]){
ansx[step]=i,ansy[step]=j,ansg[step]=1;
swap(map[step][i][j],map[step][i+1][j]);
if(dfs(step+1)) return true;
swap(map[step][i][j],map[step][i+1][j]);
}
if(i&&(map[step][i-1][j]==0)){
ansx[step]=i,ansy[step]=j,ansg[step]=-1;
swap(map[step][i][j],map[step][i-1][j]);
if(dfs(step+1)) return true;
swap(map[step][i][j],map[step][i-1][j]);
}
}
}
return false;
}
int main(){
fff();
scanf("%d",&n);
memset(map,0,sizeof(map));
for (int i=0;i<5;i++){
int t,k=0;
while (scanf("%d",&t)&&t!=0){
map[0][i][k++]=t;
}
}
if(dfs(1)){
for (int i=1;i<=n;i++){
cout<<ansx[i]<<' '<<ansy[i]<<' '<<ansg[i]<<'\n';
}
}else{
cout<<-1;
}
}