有一部分本人所写,一部分借鉴其他博客,侵删。
Fibsieve`s Fantabulous Birthday
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll res;ll ress;
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;int ccase=0;
while(n--)
{
cin>>ress;
res=sqrt(ress);
cout<<"Case "<<++ccase<<": ";
if(res*res==ress&&res%2==1)
{
cout<<1<<" "<<res<<endl;
continue;
}
if(res*res==ress&&res%2==0)
{
cout<<res<<" "<<1<<endl;
continue;
}
if(res%2==0)
{
if(res*res+res+1>=ress)
{
cout<<res+1<<" "<<ress-res*res<<endl;
}
else
{
cout<<(res+1)*(res+1)-ress+1<<" "<<res+1<<endl;
}
}
else
{
if(res*res+res+1>=ress)
{
cout<<ress-res*res<<" "<<res+1<<endl;
}
else
{
cout<<res+1<<" "<<(res+1)*(res+1)-ress+1<<endl;
}
}
}
return 0;
}
看来这道题目比较简单了,自己做的。
要分偶数和奇数,然后要再分情况。同时要注意格式。至于为什么在一个特定的点是平方数,是因为,相邻是等差数列(由于特征),那么通项公式一定是二次的,通过前几项确定了平方数。
Hdu5578
看来签到题简单也是挺正常的了。
#include<bits/stdc++.h>
using namespace std;
char a[1010];
int main()
{
int t;
cin>>t;int ccase=0;
while(t--)
{
cin>>a;
cout<<"Case #"<<++ccase<<": ";
int res=2222;
for(int i=0;i<strlen(a);i++)
{
for(int j=i+1;j<strlen(a);j++)
{
if(a[i]==a[j])
{
res=min(res,j-i);
break;
}
}
}
if(res==2222) cout<<-1<<endl;
else cout<<res<<endl;
}
return 0;
}
Hdu5583
首先,是中间一定会变小,要学会尽量化简。其次是复杂度的分析。接下来就是熟练地写加上准确度。
Cf65B
要学会使用全排列,在数字都确定的情况下,要学会从正常的角度思考。
#include<bits/stdc++.h>
using namespace std;
int num[7]={4, 8, 15, 16, 23, 42};
int a[7];
int main()
{
fflush(stdout);
cout<<"? 1 3"<<endl;
fflush(stdout);
cin>>a[1];
cout<<"? 2 4"<<endl;
fflush(stdout);
cin>>a[2];
cout<<"? 3 5"<<endl;
fflush(stdout);
cin>>a[3];
cout<<"? 4 6"<<endl;fflush(stdout);
cin>>a[4];
// num[]={4, 8, 15, 16, 23, 42};
do
{
if(num[0]*num[2]==a[1]&&num[1]*num[3]==a[2]&&num[2]*num[4]==a[3]&&num[3]*num[5]==a[4])
{
cout<<"! "<<num[0]<<" "<<num[1]<<" "<<num[2]<<" "<<num[3]<<" "<<num[4]<<" "<<num[5]<<endl;
break;
}
}while(next_permutation(num,num+6));
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
#define ll long long
char a[maxn];
ll b[maxn];
//ll jie[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(b,0,sizeof(b));
ll num;ll j=0;
cin>>a; cin>>num;
ll len=strlen(a); //cout<<a<<endl;
ll cnt=0;
for(int i=len-1;i>=0;i--)
{
b[cnt++]=(ll)(a[i]-'a'); //cout<<b[cnt-1]<<"shu"<<endl;
}
ll i=0;
// for(int j=0;j<=len-1;j++) cout<<b[j]<<endl;
b[i]+=num;// cout<<b[2]<<endl;
while(1)
{
ll temp=(b[i]+j)%26; //cout<<b[i]<<temp<<endl;
j=(b[i]+j)/26;
b[i]=temp;i++;
//cout<<j<<"j"<<endl;
//cout<<temp<<endl;
if(!j)
{
break;
}
//i++;
}
//b[i]=j;
// cout<<i<<endl;
if(i>len)
{
for(ll j=len;j<i;j++) if(b[j])
b[j]--;
// else
}
else i=len;
for(ll j=i-1;j>=0;j--)
{
cout<<char(b[j]+'a');
}
cout<<endl;
}
return 0;
}
找bug 可以从概率最大的地方去找,然后还有读题技巧。
Cf Educational Codeforces Round 65 (Rated for Div. 2)
B题
#include<bits/stdc++.h>
using namespace std;
int a[7]={0,4, 8, 15, 16, 23, 42};
int num[7];
int main()
{
int n;
fflush(stdout);
cout<<"? 1 3"<<endl;
fflush(stdout);
cin>>num[1];
cout<<"? 2 4"<<endl;
fflush(stdout);
cin>>num[2];
//fflush(stdout);
cout<<"? 3 5"<<endl;
fflush(stdout);
cin>>num[3];
cout<<"? 4 6"<<endl;
fflush(stdout);
cin>>num[4];
do
{
if(num[1]==a[1]*a[3]&&num[2]==a[2]*a[4]&&num[3]==a[3]*a[5]&&num[4]==a[4]*a[6])
{
cout<<"! "<<a[1]<<" "<<a[2]<<" "<<a[3]<<" "<<a[4]<<" "<<a[5]<<" "<<a[6]<<endl;
fflush(stdout);//不能少
break;
}
}while(next_permutation(a+1,a+7));
return 0;
}
//格式很重要的
重要的要看清楚。
Problem C、小花梨判连通
时间限制:2000ms 空间限制:512MB
Description
小花梨给出?个点,让?位同学对这?个点任意添加无向边,构成?张图。小花梨想知道对于
每个点?,存在多少个点?(包括?本身),使得?和?在这?张图中都是连通的。
Input
第一行输入两个正整数?和?,分别表示点的个数和同学数。
接下来分成?部分进行输入,每部分输入格式相同。
每部分第一行输入一个整数??,表示第?位同学连边的数目。
接下来??行,每行两个正整数?, ?,表示第?位同学将点?和点?之间进行连接。
可能会存在重边或者自环。
(1 ≤ ? ≤ 100000,1 ≤ ? ≤ 10,1 ≤ ?, ? ≤ ?, 0 ≤ ?? ≤ 200000)
Output
输出?行,第?行输出在?张图中都和编号为?的点连通的点的数目(包括?本身)
首先看错了题目,是联通的点而不是相连的点。
POJ1321
这道题目是一个简单搜索,没想到我自己写出来了,看来是太小看自己了。
由于数据规模小,很容易过了。唯一需要注意的是,要写对对象。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
char a[10][10];
int vis[10][10];int n,k;int num;int numm=0;
int v[10];
int viss[10][10];
void dfs(int i,int j)
{
viss[i][j]=1;v[j]=1;num++;
if(num>=k)
{
numm++;
return ;
}
for(int t=i+1;t<n;t++)
for(int q=0;q<n;q++)
{
if(!vis[t][q]&&!v[q]&&!viss[t][q])
{
dfs(t,q);
viss[t][q]=0;v[q]=0;
num--;
}
}
return ;
}
int main()
{
// int n,k;
// cin>>n>>k;
while(cin>>n>>k&&!(n==-1&&k==-1))
{
numm=0;
//cout<<n<<" "<<k<<endl;
memset(v,0,sizeof(v));
memset(vis,0,sizeof(vis));
getchar();
for(int i=0;i<n;i++)
{
scanf("%s",a[i]);
for(int j=0;j<n;j++)
{
// gets(a+i);
if(a[i][j]=='.') vis[i][j]=1;
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
memset(viss,0,sizeof(viss));
memset(v,0,sizeof(v));
if(!vis[i][j])
{
num=0;
dfs(i,j);
}
}
}
cout<<numm<<endl;
}
return 0;
}
POJ2251
递归复杂度到达了9e8所以加上一些运算可能超时,结果的确超时了。
要学会先用最优的啊。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
char a[31][31][31];
int vis[31][31][31];
int viss[31][31][31];
int r,l,c;int res;int sx,sy,sz,ex,ey,ez;
int dir[6][3]={0,0,1,0,0,-1,1,0,0,-1,0,0,0,-1,0,0,1,0};int re=270000;
void dfs(int i,int j,int k)
{
viss[i][j][k]=1;res++;
// cout<<res<<" "<<i<<" "<<j<<" "<<k<<endl;
if(i==ex&&j==ey&&k==ez) //re=min(res,re)
{
re=min(re,res);
return;
}
for(int q=0;q<6;q++)
{
int x=i+dir[q][0];
int y=j+dir[q][1];
int z=k+dir[q][2];
if(x<0||x>=l||y<0||y>=r||z<0||z>=c)
continue;
if(viss[x][y][z]||vis[x][y][z]) continue;
dfs(x,y,z);
viss[x][y][z]=0;
res--;
}
return ;
}
int main()
{
while(cin>>l>>r>>c&&!(l==0||r==0||c==0))
{
// int sx,sy,sz,ex,ey,ez;
//cout<<l<<r<<c<<endl;
res=0;
re=270000;
memset(vis,0,sizeof(vis));
memset(viss,0,sizeof(viss));
for(int i=0;i<l;i++)
{
for(int j=0;j<r;j++)
{
scanf("%s",a[i][j]);
for(int k=0;k<c;k++)
if(a[i][j][k]=='#') vis[i][j][k]=1;
else if(a[i][j][k]=='E')
{
ex=i;ey=j,ez=k;
}
else if(a[i][j][k]=='S') sx=i,sy=j,sz=k;
}
}
dfs(sx,sy,sz);
// cout<<sx<<" "<<sy<<" "<<sz<<endl;
// cout<<re<<endl;
if(re==270000)
{
cout<<"Trapped!"<<endl;
}
else if(sx==ex&&sy==ey&&sz==ez) cout<<0<<endl;
else
{
cout<<"Escaped in "<<re-1<<" minute(s)."<<endl;
}
}
return 0;
}
由于以前做过了,我暂时先跳过了,先做没做过的。
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<string.h>
using namespace std;
char mapp [35][35][35];
int vis[35][35][35];
int k,n,m,sx,sy,sz,ex,ey,ez;
int dir[6][3] = {{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
struct node
{
int x,y,z,step;
};
int check(int x,int y,int z)
{
if(x<0 || y<0 || z<0 || x>=k || y>=n || z>=m)
return 1;
else if(mapp[x][y][z] == '#')
return 1;
else if(vis[x][y][z])
return 1;
return 0;
}
int bfs()
{
int i;
node a,next;
queue<node> q;
a.x=sx;
a.y=sy;
a.z=sz;
a.step=0;
q.push(a);
vis[sx][sy][sz]=1;
while(!q.empty())
{
a=q.front();q.pop();
if(a.x==ex&&a.y==ey&&a.z==ez) return a.step;
for(int i=0;i<6;i++)
{
next=a;
next.x=a.x+dir[i][0];
next.y=a.y+dir[i][1];
next.z=a.z+dir[i][2];
if(check(next.x,next.y,next.z))
{
continue;
}
next.step=a.step+1;
vis[next.x][next.y][next.z]=1;
q.push(next);
}
}
return 0;
}
int main()
{
while(scanf("%d%d%d",&k,&n,&m),k+n+m)
{getchar();
for(int i=0;i<k;i++)
{
for(int j=0;j<n;j++)
{
scanf("%s",mapp[i][j]);
for(int r=0;r<m;r++)
{
if(mapp[i][j][r]=='S')
{
sx=i;
sy=j;
sz=r;
}
else if(mapp[i][j][r]=='E')
{
ex=i;
ey=j;
ez=r;
}
}
}
}
memset(vis,0,sizeof(vis));
int ans;
ans=bfs();
if(ans)
printf("Escaped in %d minute(s).\n",ans);
else cout<<"Trapped!"<<endl;}
return 0;
}
要注意复杂度,从而知道用BFS还是DFS。
POJ3278
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<string.h>
using namespace std;
const int maxx=1e6;
int s,e;
int vis[maxx+10];
struct node
{
int x,step;
//node(int xx,int stepp):x(xx),step(stepp){};
};
int check(int x)
{
if(x<0||x>=maxx||vis[x])
return 0;
return 1;
}
int bfs(int x)
{
queue<node> q;
//int s,e;
node next,a;
a.x=x;
a.step=0;
vis[x]=1;
q.push(a);
while(!q.empty())
{ a=q.front();
//vis[a.x]=1;
q.pop();
if(a.x==e)
{
return a.step;
}
next=a;
next.x=a.x+1;
if(check(next.x))
{vis[next.x]=1;
next.step=a.step+1;
q.push(next);
}
next.x=a.x-1;
if(check(next.x))
{vis[next.x]=1;
next.step=a.step+1;
q.push(next);
}
next.x=a.x*2;
if(check(next.x))
{vis[next.x]=1;
next.step=a.step+1;
q.push(next);
}
}
return -1;
}
int main()
{
int ans;
while(~scanf("%d%d",&s,&e))
{
memset(vis,0,sizeof(vis));
ans=bfs(s);
cout<<ans<<endl;
}
return 0;
}
这道题目只是BFS而已
POJ3279
这道题目在vj上的kuangbin比赛中被归类到了搜索, 其实它还算不上搜素, 是一道比较基础的枚举题目,和熄灯问题, 画家问题,拨钟问题是一类题, 如果单纯用爆搜或者枚举来考虑的话可能会超时,复杂度O(2^N*M) 需要一点点小的技巧
首先, 我们来考虑一下, 改变当前一行的只有按下当前一行或者是上一行正对着的按钮.
所以, 我们只用考虑第一行, 枚举第一行的开关操作, 然后与之对应的第二行就确定了, 第二行又确定了第三行...以此类推, 直到最后一行. 我们来判断是否全部归0
需要注意的是题中要求输出最优解, 多个最优解又要求以字典序最小的输出, 我在此用了一个字典序的状态压缩, 可以直接拿走下次用
首先注意题目类型,状态压缩,注意情况要更新。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=20;
int a[maxn][maxn];
int cur[maxn][maxn];
int ope[maxn][maxn];
int ans[maxn][maxn];
int minsteps=1<<30;
int step;
int n,m;
void press(int x,int y)//forgotten
{
cur[x][y]^=1;
cur[x+1][y]^=1;
cur[x-1][y]^=1;
cur[x][y+1]^=1;
cur[x][y-1]^=1;
}
bool solve()
{
memcpy(cur,a,sizeof(a));//difang cuole
for(int i=1;i<=m;i++)
{
if(ope[1][i])
{
press(1,i);
step++;
}
}
for(int i=2;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(cur[i-1][j]==1)
{
ope[i][j]=1;press(i,j);
step++;
}
}
}
for(int j=1;j<=m;j++)
if(cur[n][j]==1)
{
return 0;
}
return 1;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
for(int i=0;i<(1<<m);i++)
{
memcpy(cur,a,sizeof(a));//
memset(ope,0,sizeof(ope));step=0;
for(int j=0;j<m;j++)
{
ope[1][j+1]=(i>>j)&1;
// solve();
}
if(solve()>0&&step>0&&step<minsteps)
{
minsteps=step;
memcpy(ans,ope,sizeof(ope));//
}
}
if(minsteps<(1<<30))
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout<<ans[i][j]<<" ";
}
cout<<endl;
}
}
else cout<<"IMPOSSIBLE"<<endl;
return 0;
}
POJ1426
怎么都想不到是用搜索。
这博客写的很强
https://blog.csdn.net/lyy289065406/article/details/6647917
首先确定前后之间的关系,而大数的话显然就要用同余定理。然后再找规律。
敲黑板,这道题目掌握不够。
#include<iostream>
using namespace std;
int mod[550000];
int main()
{
int n;
while(cin>>n)
{
if(n==0) break;int i;
mod[1]=1%n;
for( i=2;mod[i-1]!=0;i++)
{
mod[i]=(mod[i>>1]*10+(i&1))%n;//youxianji
}
i--;
int p=0;
while(i)
{
mod[p++]=i&1;
i>>=1;
}
while(p)
{
cout<<mod[--p];
}
cout<<endl;
}
return 0;
}
要注意>>优先级
POJ3126
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1e4+2;
struct m
{
int p;
int step;
}g[maxn];
//const int maxn=1e4+2;
bool vis[maxn];
bool judge(int i)
{
if(i==2||i==3)
{
return true;
}
else if(i<=1||i%2==0)
return false;
else
{
for(int ii=3;ii*ii<=maxn;ii+=2)//
{
if(i%ii==0) return false;
}
return true;
}
}
int a,b;
void bfs()
{
int head=0;int tail=0;
g[head].p=a;
g[tail++].step=0;
vis[a]=1;
while(head!=tail+1)
{
m x=g[head++];
//if()
int shu=x.p;
if(shu==b)
{
cout<<x.step<<endl;
return ;
}
int ge=shu%10;
int shi=(shu/10)%10;
for(int i=1;i<=9;i+=2)
{
int q=shu/10*10+i;
if(judge(q)&&!vis[q])
{
vis[q]=1;m xx;
xx.step=x.step+1;
xx.p=q;
g[tail++]=xx;
}
}
for(int i=0;i<=9;i++)
{
int q=shu/100*100+i*10+ge;
if(judge(q)&&!vis[q])
{
vis[q]=1;m xx;
xx.step=x.step+1;
xx.p=q;
g[tail++]=xx;
}
}
for(int i=0;i<=9;i++)
{
int q=shu/1000*1000+i*100+shi*10+ge;
if(judge(q)&&!vis[q])
{
vis[q]=1;m xx;
xx.step=x.step+1;
xx.p=q;
g[tail++]=xx;
}
}
for(int i=1;i<=9;i++)
{
int q=i*1000+shu%1000;
if(judge(q)&&!vis[q])
{
vis[q]=1;m xx;
xx.step=x.step+1;
xx.p=q;
g[tail++]=xx;
}
}
}
cout<<"Impossible"<<endl;
return ;
}
int main()
{
int t;//int a,b;
cin>>t;
while(t--)
{
cin>>a>>b;
memset(vis,0,sizeof(vis));
bfs();
}
return 0;
}
要自己写一遍,应该是能写出来的吧。
还有偶数和奇数缩小判断规模
POJ3087
模拟水题。
#include<iostream>
#include<cstring>
#include<map>
#include<cstdio>
using namespace std;
//map<char*,bool>book;
int main()
{
int n;
scanf("%d",&n); char a[150];
char b[150];
char s[310];
// char ss[310];
for(int i=1;i<=n;i++)
{
int t;
//cin>>t;
scanf("%d",&t);
scanf("%s",a);
scanf("%s",b);
scanf("%s",s);
// cin>>b;
//cin>>s;
int step=0;
map<string,bool>book;//weizhi
while(true)
{
int p=0;
char ss[310];
for(int ii=0;ii<t;ii++)
{
ss[p++]=b[ii];
ss[p++]=a[ii];
}
ss[p]='\0';//
step++;//book[ss]=1;
//cout<<ss<<endl;
if(!strcmp(ss,s))
{
cout<<i<<" "<<step<<endl;
break;
}
if(strcmp(s,ss)&&book[ss])
{
cout<<i<<" "<<-1<<endl;
break;
}
book[ss]=true;//weizhi
for(int ii=0;ii<t;ii++)
{
a[ii]=ss[ii];
b[ii]=ss[ii+t];
}
a[t]='\0';
b[t]='\0';//
/* for(int ii=0;ii<t;ii++)
a[ii]=ss[ii];
a[t]='\0';
for(int ii=n,j=0;ii<2*t;ii++,j++)
b[j]=ss[ii];
b[t]='\0';*/
}
}
return 0;
}
主要是调试程序的方法。
Lightoj1020
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
int t;
cin>>t;int ccase=0;
char s[10];
while(t--)
{
ll a,b;
//cin>>a>>b;
scanf("%lld",&a);
scanf("%s",s);
cout<<"Case "<<++ccase<<": ";
if(strcmp(s,"Bob")==0)
if(a%3==0) printf("Alice\n");else printf("Bob\n");
else
{
if(a%3==1) printf("Bob\n");
else printf("Alice\n");
}
}
return 0;
}
首先靠感觉是很有可能会错的,所以要从小规模考虑,分情况考虑。
然后在本人的电脑可能显示的格式是和评测的有所不同,所以不要随便忽略细节。
LightOJ 1078
同余性质
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;int ccase=0;
while(n--)
{
int a,b;
cin>>a>>b;
cout<<"Case "<<++ccase<<": ";
int s=b%a;int t=1;
while(s%a)
{
s=(s*10+b)%a;//个位//
t++;
}
cout<<t<<endl;
}
return 0;
}
、LightOJ 1116
#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long
int main()
{
int n;
cin>>n;int ccase=0;
while(n--)
{
ll a,b;
cin>>a;
cout<<"Case "<<++ccase<<": ";
if(a%2==1)
cout<<"Impossible"<<endl;
else
{ll t=0;
ll aa=a;
if(a%2==0)
{
while(a%2==0)
{
a/=2;
t++;
}
}
cout<<a<<" "<<aa/a<<endl;
}
}
return 0;
}
太简单了就不讲了
LightOJ 1148
#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long
const int maxn=1e6+10;
int a[55];
int b[maxn];
int main()
{
int t;
cin>>t;
int ccase=0;
while(t--)
{
int n;
cin>>n;
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
cin>>a[i];
//b[a[i]]++;
}
sort(a,a+n);int p=0;int res=0;
while(p<n)
{
int q=1;
while((p+1<n)&&a[p]==a[p+1]) q++,p++;
int r=(q+a[p])/(a[p]+1)*(a[p]+1)-q;
res+=r;
p++;
}
cout<<"Case "<<++ccase<<": ";
cout<<res+n<<endl;
}
return 0;
}
一遍过,太简单了。
LightOj 1179
约瑟夫问题
#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long
const int maxn=1e6+10;
int a[55];
int b[maxn];
int main()
{
int t;
cin>>t;
int ccase=0;
while(t--)
{
int n;int k;
cin>>n; cin>>k; int s=0;//digui ,xunhuan
for(int j=1;j<n;j++)
{
s=(s+k)%(j+1);
}
cout<<"Case "<<++ccase<<": ";
cout<<(s+1)<<endl;
}
return 0;
}
因为n和k的范围都较大所以不能直接模拟,要推导出规律f(n) = (f(n-1) + k) % n。
//递归,从底往上
// f[1] = 0; //当一个人的时候,出队人员编号为0
// f[n] = (f[n-1] + m)%n //m表示每次数到该数的人出列,n表示当前序列的总人数
从小规模很重要
逆向从易 到难
LightOJ1275
看清T为自变量, 一元二次方程
由此可看搜索题目是和它同等级的简单了,那我真是弱到掉渣了呢
#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long
const int maxn=1e6+10;
int a[55];
int b[maxn];
int main()
{
int t;
cin>>t;
int ccase=0;
while(t--)
{
int n,c;int s=0;
cin>>n>>c;
cout<<"Case "<<++ccase<<": ";
if(n!=0) s=c/(2*n);
if(n==0) cout<<0<<endl;
//int s=(c)/(2*n);//可能为小数
else if(-n*s*s+s*c>=-n*(s+1)*(s+1)+(s+1)*c)//等号取不取
cout<<s<<endl;
else cout<<s+1<<endl;
}
return 0;
}
LightOJ 1294
#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long
const int maxn=1e6+10;
int a[55];
int b[maxn];
int main()
{
int t;
cin>>t;
int ccase=0;
while(t--)
{
ll n,m;
cin>>n>>m;
cout<<"Case "<<++ccase<<": ";
cout<<n/(2)*m<<endl;
}
return 0;
}
首先范围,然后是化简。一开始就要尽量简化。
POJ3414
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int a,b,c;bool flag=false;
const int n=110;
string str[10]={"","FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","PORR(2,1)"};
int vis[n][n];
struct node
{
int x,y;//
int step;
string s;//记录路径
node(int x,int y,int step,string s):x(x),y(y),step(step),s(s){}
};
void bfs()
{
queue<node> q;
q.push(node(0,0,0,"0"));
vis[0][0]=1;
while(!q.empty())
{
node qq=q.front();
q.pop();
if(qq.x==c||qq.y==c)
{
flag=true;
cout<<qq.step<<endl;
for(int i=0;i<qq.s.length();i++)
{
cout<<str[qq.s[i]-'0']<<endl;
}
return ;
}
if(qq.x<a)
{
if(!vis[a][qq.y])
{
vis[a][qq.y]=1;
q.push(node(a,qq.y,qq.step+1,qq.s+'1'));
}
}
if (qq.y<b)
{
if(!vis[qq.x][b])
{
vis[qq.x][b]=1;
q.push(node(qq.x,b,qq.step+1,qq.s+'2'));
}
}
if(qq.y!=0)
{
if(!vis[qq.x][0])
{
vis[qq.x][0]=1;
q.push(node(qq.x,0,qq.step+1,qq.s+'4'));
}
}
if(qq.x!=0)
{
if(!vis[0][qq.y])
{
vis[0][qq.y]=1;
q.push(node(0,qq.y,qq.step+1,qq.s+'3'));
}
}
if(qq.x!=0&&qq.y<b)
{
int xx,yy;
if(qq.x<=b-qq.y)
{
xx=0;
yy=qq.y+qq.x;
}
else
{
xx=qq.x-b+qq.y;
yy=b;
}
if(!vis[xx][yy])
{
vis[xx][yy]=1;
q.push(node(xx,yy,qq.step+1,qq.s+'5'));
}
}
if(qq.y!=0&&qq.x<a)
{
int xx,yy;
if(qq.y<=a-qq.x)
{
yy=0;
xx=qq.y+qq.x;
}
else
{
yy=qq.y-a+qq.x;
xx=a;
}
if(!vis[xx][yy])
{
vis[xx][yy]=1;
q.push(node(xx,yy,qq.step+1,qq.s+'6'));
}
}
}
}
int main()
{
cin>>a>>b>>c;
bfs();
if(!flag)
{
cout<<"impossible"<<endl;
}
return 0;
}
BFS,OJ崩了
LightOJ 1297
首先要注意解方程先要不等式,再是求导啊,要看实际意义。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;int ccase=0;
while(t--)
{
double w,l;
cin>>w>>l;
cout<<"Case "<<++ccase<<": ";
double a=12;
double b=(-4)*(w+l);
double c=(w*l);
double in=sqrt(b*b-4*a*c);
//double ans1=(-b+in)/2/a;
double ans=(-b-in)/2/a;
printf("%.6lf\n",(l-2*ans)*(w-2*ans)*ans);
}
return 0;
}
注意格式输出
Lightoj 1311
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;int ccase=0;
while(t--)
{
double v1,v2,v3,a1,a2;double t;
//t=max()
cin>>v1>>v2>>v3>>a1>>a2;
t=max(v1/a1,v2/a2);//keyi buyiyangchang
cout<<"Case "<<++ccase<<": ";
printf("%.6lf ",v1*v1/2/a1+v2*v2/2/a2);
printf("%.6lf\n",t*v3);
}
return 0;
}
可以不同时停下来。还是思路可能会错。
Hdu 1024
首先定义dp[i][j]为状态: 在前j个数中恰好选出i组数的最大和
得出状态转移方程dp[j][j]=max(dp[i][j−1],dp[i][j−1]+a[j],dp[i−1][k]+a[j](0<k<j)) dp[j][j] = max(dp[i][j-1], dp[i][j-1]+a[j], dp[i-1][k]+a[j](0<k<j) )dp[j][j]=max(dp[i][j−1],dp[i][j−1]+a[j],dp[i−1][k]+a[j](0<k<j))
意义依次为不取第j个数, 取第j个数归入当前组, 取第j个数归入新的组.
显然n2 n^2n
2
的复杂度, 不管是空间还是时间都无法通过, 我们考虑优化, 首先dp[i][j-1]和 dp[i-1][k]+aj其实和dp[i-1][k]+aj含义是相似的, 试想不取当前这个数, 其实就是在之后的某个地方开了新的组把这个数弹出来了.
而且和背包问题一样, 只和dp[i-1]这一层有关, 我们用一维数组来滚动就可以啦, 顺序不变
最后dp[i-1][k]其实就是上一组j之前最大的dp, 我们用一个数组来存一下就好了
首先要注意无论如何都可以分为i组。
先写递推式,再化简。那么,然后再直接前j-1求最大值,存在数组里
要注意每次的初始化
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int mm=0x7fffffff;
int dp[maxn];
int num[maxn];
int pre[maxn];//
int main()
{
int n;int m;
while(cin>>m>>n)
{
memset(dp,0,sizeof(dp));
memset(pre,0,sizeof(pre));
int temp=-mm;
for(int i=1;i<=n;i++)
cin>>num[i];
for(int i=1;i<=m;i++)
{
temp=-mm;//
for(int j=i;j<=n;j++)
{
dp[j]=max(dp[j-1],pre[j-1])+num[j];
pre[j-1]=temp;
temp=max(temp,dp[j]);
}
}
cout<<temp<<endl;
}
return 0;
}
Hdu1029
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+2;
int a[maxn];
int main()
{
int n;
while(cin>>n)
{
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
cout<<a[(n+1)/2]<<endl;
}
return 0;
}
好像可以dp做,但是原谅我不想那么麻烦,留待以后去做。
Hdu 1069
#include<bits/stdc++.h>
using namespace std;
struct node
{
int l,w,h;
}nod[181];
int dp[181];
bool cmp(node a,node b)
{
if(a.l==b.l) return a.w<b.w;
return a.l<b.l;
}
int main()
{
int n;int ccase=0;
while(scanf("%d",&n)&&n)
{
memset(dp,0,sizeof(dp));int len=0;
for(int i=1;i<=n;i++)
{
int x,y,z;
cin>>x>>y>>z;
nod[len].l=x;nod[len].w=y;nod[len++].h=z;
nod[len].l=x;nod[len].w=z;nod[len++].h=y;
nod[len].l=y;nod[len].w=x;nod[len++].h=z;
nod[len].l=y;nod[len].w=z;nod[len++].h=x;
nod[len].l=z;nod[len].w=y;nod[len++].h=x;
nod[len].l=z;nod[len].w=x;nod[len++].h=y;
}
sort(nod,nod+len,cmp);dp[0]=nod[0].h;
for(int i=1;i<len;i++)
{
int mm=0;
for(int j=0;j<i;j++)
{
if(nod[i].l>nod[j].l&&nod[i].w>nod[j].w)
mm=max(mm,dp[j]);
}
dp[i]=nod[i].h+mm;
}
int mmm=0;
for(int i=0;i<len;i++)
mmm=max(mmm,dp[i]);//
cout<<"Case "<<++ccase<<": "<<"maximum height = ";
cout<<mmm<<endl;
}
return 0;
}