官方题解:http://blog.sina.com.cn/duoxiao2015
队友回家了。。于是开启单刷模式。。。但是中间吃饭+被叫去开会,于是比赛时就AC了3题,排167名,开完会回来继续把第4题写完,结果刚好比赛结束,于是就变成赛后AC
HDOJ5327
题意:问[l,r]中有几个数是各个位的数字均不相同
思路:水题,先预处理下就好
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAXN=100000+10;
int T,n,m,k,l,r;
int a[MAXN];
bool fun(int x){
bool num[15]={0};
while(x){
int c=x%10;
if(num[c])return 0;
else num[c]=1;
x/=10;
}
return 1;
}
void init(){
a[0]=0;
for(int i=1;i<MAXN;i++){
a[i]=a[i-1];
if(fun(i))a[i]++;
}
//memset(a,0,sizeof(a));
}
void work(){}
int main(){
#ifdef DEBUG
freopen("CBin.txt","r",stdin);
//freopen("CBout.txt","w",stdout);
#endif
init();
cin>>T;
while(T--){
cin>>l>>r;
cout<<a[r]-a[l-1]<<"\n";
}
return 0;
}
HDOJ5328
题意:给一个长为n的序列,问能形成等差数列或者等比数列的连续子序列最长为多少
思路:水题,但不知为何我O(n)的方法会超时,加上快速读入就过了。。。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAXN=1000000+10;
const int INF=1e9*2;
const double eps=1e-9;
int T,n,m,k,l,r;
int a[MAXN];
void init(){
//memset(a,0,sizeof(a));
}
int work(){
int ap=INF,ka=1,kg=1,k;
double gp=INF;
if(n>1){ap=a[1]-a[0];ka++;}
if(n>1&&a[0]!=0){gp=1.0*a[1]/a[0];kg++;}
k=max(ka,kg);
for(int i=2;i<n;i++){
int nap=a[i]-a[i-1];
if(nap==ap)ka++;
else{
ap=nap;
k=max(ka,k);
ka=2;
}
double ngp;
if(a[i]!=0){
ngp=1.0*a[i]/a[i-1];
if(abs(ngp-gp)<eps)kg++;
else{
gp=ngp;
k=max(kg,k);
kg=2;
}
}else{
gp=INF;
kg=1;
}
}
k=max(k,ka);
k=max(k,kg);
return k;
}
template <class T>
inline bool read(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0; //EOF
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
int main(){
#ifdef DEBUG
freopen("CBin.txt","r",stdin);
//freopen("CBout.txt","w",stdout);
#endif
cin>>T;
while(T--){
init();
read(n);
if(n==0){cout<<"0\n";continue;}
for(int i=0;i<n;i++)read(a[i]);
//putchar(work()+'0');
cout<<work()<<"\n";
}
return 0;
}
HDOJ5335
题意:给一个n*m大小,且仅有01的图,问从左上到右下所经过的路径连起来所代表的二进制最小为多少
思路: 先bfs找到距离右下最近且与左上仅由0相连的0,再从这些0出发进行bfs,剪枝剪掉肯定不为最小的路径,bfs时记录方向,最后找出这条路径并输出结果
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int MAXN=1000+10;
int T,n,m;
bool g[MAXN][MAXN],vis[MAXN][MAXN];
int dis[MAXN][MAXN],disf[5][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}};
bool res[MAXN<<1];
int p;
void init(){
getchar();
for (int i=0;i<n;++i){
for (int j=0;j<m;++j){
char c=getchar();
g[i][j]=c-'0';
}
getchar();
}
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
}
bool check(int x,int y){
if(x<0||y<0||x>=n||y>=m)return 0;
else return 1;
}
int bfs1(){
queue<int>q;
int now,x,y,k=0;
if(g[0][0]==1)return 0;
q.push(0);
while(!q.empty()){
now=q.front();
x=now/m;
y=now%m;
for(int i=1;i<=4;i++){
int nx=x+disf[i][0];
int ny=y+disf[i][1];
if(check(nx,ny)&&!g[nx][ny]&&!dis[nx][ny]){
dis[nx][ny]=i;
q.push(nx*m+ny);
}
}
k=max(k,x+y);
q.pop();
}
return k;
}
void bfs2(int k){
queue<int>q;
queue<int>q2[2];
int now,x,y;
if(k==0)q.push(0);
else
for(int i=0;i<=k;i++){
x=i;
y=k-i;
if(check(x,y)&&dis[x][y])q.push(x*m+y);
}
while(1){
while(!q.empty()){
now=q.front();
x=now/m;
y=now%m;
for(int i=1;i<=2;i++){
int nx=x+disf[i][0];
int ny=y+disf[i][1];
if(check(nx,ny)&&!dis[nx][ny]){
dis[nx][ny]=i;
q2[g[nx][ny]].push(nx*m+ny);
}
}
q.pop();
}
if(q2[0].empty()&&q2[1].empty())break;
if(q2[0].empty()){
while(!q2[1].empty()){
q.push(q2[1].front());
q2[1].pop();
}
}else {
while(!q2[1].empty())q2[1].pop();
while(!q2[0].empty()){
q.push(q2[0].front());
q2[0].pop();
}
}
}
}
void disp(int k){
int x=n-1,y=m-1;
memset(res,0,sizeof(res));
p=0;
for(int i=n+m-2;i>=k;i--){
res[p++]=g[x][y];
int f=dis[x][y];
x-=disf[f][0];
y-=disf[f][1];
}
p--;
if(res[p])printf("%d",res[p]);
p--;
for(;p>=0;p--){
printf("%d",res[p]);
}
printf("\n");
}
int main(){
#ifdef DEBUG
freopen("CBin.txt","r",stdin);
//freopen("CBout.txt","w",stdout);
#endif
cin>>T;
while(T--){
cin>>n>>m;
init();
int k=bfs1();
if(k==0&&n==1&&m==1){cout<<g[0][0]<<"\n";continue;}
if(k==n+m-2){cout<<"0\n";continue;}
bfs2(k);
disp(k);
}
return 0;
}
HDOJ5536
题意:就是给你r*c的图,图上有n个水滴,告诉你每个水滴的坐标以及水滴的大小,在xy处有个水滴爆炸,问第T秒时各个水滴的状态,已经爆炸输出0和爆炸时间,未爆输出1和第T秒时的大小
爆炸与变大的游戏规则就是十滴水那款小游戏的规则,有玩过的就可以直接跳过规则说明部分
规则:水滴爆炸时该位置水滴消失并向4个方向发射一个小水滴,每个运动的小水滴与静止的水滴碰撞则会融合,融合后的大小为原大小加1,如果大于4,则该位置发生爆炸
思路:暴力模拟
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int MAXN=100+10;
int T,n,m,time,num;
int g[MAXN][MAXN],gt[MAXN][MAXN];
int disf[5][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}};
int x,y;
struct Point{
int x;
int y;
}poi[MAXN];
struct Move{
int x;
int y;
int disx;
int disy;
};
template <class T>
inline bool read(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0; //EOF
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
void init(){
memset(g,0,sizeof(g));
memset(gt,0,sizeof(gt));
for(int i=0;i<num;i++){
int x,y,c;
read(x);
read(y);
read(c);
g[x][y]=c;
poi[i]=(Point){x,y};
}
read(x);
read(y);
}
bool check(int x,int y){
if(x<=0||y<=0||x>n||y>m)return 0;
else return 1;
}
void bfs(){
queue<Move>q[2];
queue<Point>p;
int f=0;
int t=0;
q[f].push((Move){x,y,1,0});
q[f].push((Move){x,y,-1,0});
q[f].push((Move){x,y,0,1});
q[f].push((Move){x,y,0,-1});
while(1){
t++;
while(!q[f].empty()){
Move now=q[f].front();
int x=now.x+now.disx;
int y=now.y+now.disy;
if(check(x,y)){
if(g[x][y]){
g[x][y]++;
p.push((Point){x,y});
}
else{
now.x=x;
now.y=y;
q[f^1].push(now);
}
}
q[f].pop();
}
while(!p.empty()){
Point now=p.front();
int x=now.x;
int y=now.y;
if(g[x][y]>4){
g[x][y]=0;
gt[x][y]=t;
q[f^1].push((Move){x,y,1,0});
q[f^1].push((Move){x,y,-1,0});
q[f^1].push((Move){x,y,0,1});
q[f^1].push((Move){x,y,0,-1});
}
p.pop();
}
f^=1;
if(q[f].empty())break;
if(t>=time)break;
}
}
int main(){
#ifdef DEBUG
freopen("CBin.txt","r",stdin);
//freopen("CBout.txt","w",stdout);
#endif
while(~scanf("%d%d%d%d",&n,&m,&num,&time)){
init();
bfs();
for(int i=0;i<num;i++){
if(gt[poi[i].x][poi[i].y]){
printf("0 %d\n",gt[poi[i].x][poi[i].y]);
}else{
printf("1 %d\n",g[poi[i].x][poi[i].y]);
}
}
}
return 0;
}