T1:
是一道简单的实数二分,不多说,注意精度问题!!
#include<cstdio>
#include<cmath>
using namespace std;
double emo=0.000000000001;//精度
double L,R;
inline double f(double x)
{
return (double)exp(x*log(2))+exp(x*log(3))-exp(x*log(4))//等于2的x次幂+3的x次幂-4的x次幂;
}
int main(void)
{
scanf("%lf%lf",&L,&R);
while(R-L>emo){
double mid=(L+R)/2.0;
if(f((double)mid)<=0)R=mid;
else L=mid;
}
printf("%.10lf",L);
}
T2:
乍眼一看是一道写过的状压DP,其实仔细分析一下便可以知道,它的棋面只有2格宽,进一步分析可以得知,上下的状态必定是一样的,所以只用看一行。问题转化为:一条棋面,用1*1的方块或者1*2的方块填满。那不就是跳楼梯吗?
普通DP直接过
#include<cstdio>
using namespace std;
int n;
long long f[32];
int main(void)
{
scanf("%d",&n);
f[1]=1ll;f[0]=1ll;
for(int i=2;i<=n;i++){
f[i]=f[i-1]+f[i-2];
}
printf("%lld",f[n]);
}
//十六行结束战斗
T3:
第一眼确实看出来了是一道贪心题,但是排序的方案出了问题,并不是按照y为第一关键字,c为第二关键字,而应该是那c+y的和进行排序
证明:
比较max(sum-bi,sum+ai-bj)和max (sum-bj, sum+aj-bi)的大小。明显,sum-bi<sum+aj-bi,sum-bj<sum+ai-bj。所以,只需要比较sum+ai-bj和sum+aj-bi的大小。假定sum+ai-bj<sum+aj-bi,那么,我们可以得到ai+bi<aj+bj。
从上面的分析可以看出,如果i比j放在前面更优,就一定有ai+bi<aj+bj。那么,只需要按照a+b为关键字升序排序,即可得到最优排列,计算出最大的伤害值,即为答案。
#include<cstdio>
#include<algorithm>
using namespace std;
struct karsa{
int y,c;
int val;
}a[50005];
int n;
int sum,maxx=-0x7fffffff;
inline bool tmp(karsa x,karsa y){return x.y==y.y?x.c<y.c:x.y<y.y;}
int main(void)
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].y,&a[i].c);
}
sort(a+1,a+1+n,tmp);
sum=a[1].y;
for(int i=2;i<=n;i++){
a[i].val=sum-a[i].c;
sum+=a[i].y;
}
for(int i=1;i<=n;i++)maxx=max(maxx,a[i].val);
printf("%d",maxx);
}
T4:
其实就是一道模拟题,但是本人太蠢了,没有读懂约瑟夫游戏要干什么,所以就没做TAT
不难发现,将数据用对列存储起来就可以非常方便的进行修改
核心:
q.push(q.front()); q.pop(); q.pop();
这一行就巧妙的实现了隔一个踢出一个的操作
#include<cstdio>
#include<queue>
using namespace std;
int n,win,ans;
queue<int> q;
int main(void)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)q.push(i);
while(1){
while(q.size()>1){
q.push(q.front());
q.pop();
q.pop();
}
if(win==q.front()){
ans=win;
break;
}
win=q.front();
q.pop();
for(int i=1;i<=win;i++)q.push(i);
}
printf("%d",ans+n);
}
T5:
01背包,板子都不带改的,铭记复习
#include<cstdio>
#include<algorithm>
using namespace std;
struct tk{
int value;
int rank;
}a[30];
int n,m;
int f[300000];
int ans=0;
int main(void)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d%d",&a[i].value,&a[i].rank);
for(int i=1;i<=m;i++){
for(int j=n;j>=a[i].value;j--){
f[j]=max(f[j],f[j-a[i].value]+a[i].value*a[i].rank);
}
}
for(int i=n;i>=0;i--)ans=max(ans,f[i]);
printf("%d\n",ans);
}
T6:
刚开始以为是道铁铁的DP题,本来想先写暴力DFS然后写个“NB”的DP来对拍的。可是没想到正解就是DFS,可自己DFS忘记了特判输出-1的情况,痛失此题QAQ
#include<cstdio>
#include<algorithm>
using namespace std;
int N,A,B;
int mov[210];
int INF=0x7fffff;
int ans=0x7fffff;
bool vis[210];
inline void dfs(int now,int fath,int dep)
{
if(now>N || now<1 || vis[now]==1)return ;
//d[now]=d[fath]+1;
if(ans<dep)return ;
vis[now]=1;
if(now==B){
ans=min(ans,dep);
return ;
}
dfs(now+mov[now],now,dep+1);
dfs(now-mov[now],now,dep+1);
vis[now]=0;
}
int main(void)
{
scanf("%d%d%d",&N,&A,&B);
for(int i=1;i<=N;i++){scanf("%d",&mov[i]);}
dfs(A,0,0);
printf("%d",ans==INF?-1:ans);
}
T7:
不多说了,并查集做过的原题,精髓是将敌人的编号设为x+n,朋友就是x本身,最后计算头儿的个数来计算团伙个数
#include<cstdio>
using namespace std;
int n,m;
int fa[3010];
int size[3010];
int ans=0;
inline int find(int x)
{
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
int main(void)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n*2;i++)fa[i]=i;
for(int i=1;i<=m;i++){
int p,x,y;
scanf("%d%d%d",&p,&x,&y);
if(p==0){
fa[find(x)]=find(y);
}
else{
fa[find(x+n)]=find(y);//精髓
fa[find(y+n)]=find(x);
}
}
for(int i=1;i<=n;i++){
if(fa[i]==i)ans++;
}
printf("%d",ans);
}
T8:
模拟,被整吐了
WA码:
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
struct node {
int d;
int x,y;
bool flag;
} a,b;
int T,n;
int mov[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool f=0;
bool m1[1010][1010];
bool m2[1010][1010];
int main(void) {
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
scanf("%d%d%d",&a.x,&a.y,&a.d);
scanf("%d%d%d",&b.x,&b.y,&b.d);
a.x++;a.y++;a.flag=0;
b.x++;b.y++;b.flag=0;
memset(m1,0,sizeof(m1));
memset(m2,0,sizeof(m2));
f=0;
for(int i=0;i<=n+1;i++)m1[i][0]=m2[i][0]=1;
for(int i=0;i<=n+1;i++)m1[i][n+1]=m2[i][n+1]=1;
for(int i=0;i<=n+1;i++)m1[0][i]=m2[0][i]=1;
for(int i=0;i<=n+1;i++)m1[n+1][i]=m2[n+1][i]=1;
while(a.flag!=1 || b.flag!=1) {
m1[a.x][a.y]=1;m2[b.x][b.y]=1;
if(a.x==b.x && a.y==b.y) {
f=1;
break;
}
int pa=0,pb=0;
if(m1[a.x][a.y+1]==1 && a.d==1)
a.d=2,pa++;
if(m1[a.x-1][a.y]==1 && a.d==2)
a.d=3,pa++;
if(m1[a.x][a.y-1]==1 && a.d==3)
a.d=0,pa++;
if(m1[a.x+1][a.y]==1 && a.d==0)
a.d=1,pa++;
if(m1[a.x][a.y+1]==1 && m1[a.x-1][a.y]==1 && m1[a.x][a.y-1]==1 && m1[a.x+1][a.y]==1)a.flag=1;
if(m2[b.x+1][b.y]==1 && b.d==0)
b.d=3,pb++;
if(m2[b.x][b.y-1]==1 && b.d==3)
b.d=2,pb++;
if(m2[b.x-1][b.y]==1 && b.d==2)
b.d=1,pb++;
if(m2[b.x][b.y+1]==1 && b.d==1)
b.d=0,pb++;
if(m2[b.x][b.y+1]==1 && m2[b.x-1][b.y]==1 && m2[b.x][b.y-1]==1 && m2[b.x+1][b.y]==1)b.flag=1;
if(a.d==1 && a.flag==0) {
a.y+=1;
// if(a.y==n)
// a.d=2;
} else {
if(a.d==2 && a.flag==0) {
a.x-=1;
// if(a.x==1)
// a.d=3;
} else {
if(a.d==3 && a.flag==0) {
a.y-=1;
// if(a.y==1)
// a.d=0;
} else {
if(a.d==0 && a.flag==0) {
a.x+=1;
// if(a.x==n)
// a.d=1;
}
}
}
}
if(b.d==1 && b.flag==0) {
b.y+=1;
// if(b.y==n)
// b.d=0;
} else {
if(b.d==2 && b.flag==0) {
b.x-=1;
// if(b.x==1)
// b.d=1;
} else {
if(b.d==3 && b.flag==0) {
b.y-=1;
// if(b.y==1)
// b.d=2;
} else {
if(b.d==0 && b.flag==0) {
b.x+=1;
// if(b.x==n)
// b.d=3;
}
}
}
}
}
if(f==1) {
printf("%d %d\n",b.x-1,b.y-1);
} else {
printf("-1\n");
}
}
}