A.Difference Max
考试情况(正解)
日常水题
求出b-c即可
code
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b,c,d;
cin>>a>>b>>c>>d;
cout<<b-c;
return 0;
}
B.Round Down
考试情况(正解)
数据范围过大,直接考虑字符串
将小数点以前的所有数字输出即可
code
#include<bits/stdc++.h>
using namespace std;
int main()
{
string s;
cin>>s;
for(int i=0;i<s.size();i++)
{
if(s[i]=='.') return 0;
cout<<s[i];
}
return 0;
}
C.Doubled
考试情况(正解)
无脑暴力即可
code
#include<bits/stdc++.h>
using namespace std;
int main()
{
long long n;
cin>>n;
for(long long i=1;;i++)
{
if(i<=9)
{
if(i*10+i>n){
cout<<i-1;
return 0;
}
}
else if(i<=99)
{
if(i*100+i>n){
cout<<i-1;
return 0;
}
}
else if(i<=999)
{
if(i*1000+i>n){
cout<<i-1;
return 0;
}
}
else if(i<=9999)
{
if(i*10000+i>n){
cout<<i-1;
return 0;
}
}
else if(i<=99999)
{
if(i*100000+i>n){
cout<<i-1;
return 0;
}
}
else if(i<=999999)
{
if(i*1000000+i>n){
cout<<i-1;
return 0;
}
}
else if(i<=9999999)
{
if(i*10000000+i>n){
cout<<i-1;
return 0;
}
}
}
return 0;
}
D.Hanjo
考试情况
日常误以为是dp,看着像是一个棋盘类的状压dp,想不出来该怎么写,就放弃了
正解
实则只是一个垃(N)圾(B)的暴搜!
搜索每一种砖块放置情况,再不断回溯
因为题目所给的砖块一定能刚好铺满所有地板
所以只需要两格砖都有地方铺,一格砖也就一定能放下
具体细节见代码
code
#include<bits/stdc++.h>
using namespace std;
const int maxn=20;
int n,m,a,b,ans,vis[maxn][maxn];
void dfs(int x,int y,int s)
{
if(!s)
{
ans++;
return;
}
if(y==m+1)
{
dfs(x+1,1,s);//换行
return;
}
if(x==n+1) return;//出边界
dfs(x,y+1,s);//铺一格砖
if(!vis[x][y]&&x<n&&!vis[x+1][y])//竖铺两格砖
{
vis[x][y]=vis[x+1][y]=1;
dfs(x,y+1,s-1);
vis[x][y]=vis[x+1][y]=0;//回溯
}
if(!vis[x][y]&&y<m&&!vis[x][y+1])//横铺两格砖
{
vis[x][y]=vis[x][y+1]=1;
dfs(x,y+1,s-1);
vis[x][y]=vis[x][y+1]=0;//回溯
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&a,&b);
dfs(1,1,a);
printf("%d\n",ans);
return 0;
}
E.Filters
考试情况
考试时码了这道题很久
最后还是会超时
写了一个n*q的算法,但还是T了8组
Wrong code
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N],x[N],t[N];
int f[N],k=0,f1=0,f2=0;
int main()
{
int n,q;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&t[i]);
scanf("%d",&q);
for(int i=1;i<=q;i++) scanf("%d",&x[i]);
for(int i=1;i<=n;i++) f[i]=1e9+1;
for(int i=1;i<=q;i++)
{
int ans=x[i];
f1=0;
f2=0;
k=0;
for(int j=1;j<=n;j++)
{
if(t[j]==1) ans+=a[j];
if(t[j]==2)
{
if(a[j]>=ans)
{
if(f1==0) k=j,f1=1;
if(f[j]!=1e9+1)
{
f2=1;
printf("%d\n",f[j]);
break;
}
ans=a[j];
}
}
if(t[j]==3)
{
if(a[j]<=ans)
{
if(f1==0) k=j,f1=1;
if(f[j]!=1e9+1)
{
f2=1;
printf("%d\n",f[j]);
break;
}
ans=a[j];
}
}
}
if(f2==1) continue;
printf("%d\n",ans);
if(f1==1) f[k]=ans;
}
return 0;
}
正解
看了许多正解,都是拿我不会的线段树来写的裂开
但是!
我看到了一个和我想法接近的代码,就是预处理出一个表达式
使每次输入都可以直接用这个表达式计算结果
即找到最终结果需要被比较的最大值和最小值,再加上所有被加的数字
所以
代码如下
code
#include<bits/stdc++.h>
using namespace std;
int n,q;
long long maxn=-1e16,minn=1e16,P;
int main()
{
cin>>n;
while(n--)
{
int a,t;
cin>>a>>t;
if(t==1) P+=a;
else if(t==3) minn=min(minn,a-P),maxn=min(maxn,a-P);
else maxn=max(maxn,a-P),minn=max(minn,a-P);
}
cin>>q;
while(q--)
{
long long x;
cin>>x;
cout<<max(min(x,R),L)+P<<endl;
}
}
总结
1.还是不要多想dp了,老老实实想想贪心与暴搜