P1548 [NOIP1997 普及组] 棋盘问题
题意
计算一个长方形中包含的正方形和长方形个数
思路
- 暴力模拟每一种长方形和正方形的个数
- 个数等于(当前长宽分别为i,j)(n-i+1)*(m-j+1)
坑点
- 无
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
int maxn=max(n,m);
int minn=min(n,m);
int sum1=0,sum2=0;//统计正方形,长方形的个数
for(int i=1;i<=maxn;i++)//遍历正方形
{
sum1+=(n-i+1)*(m-i+1);
}
for(int i=1;i<=maxn;i++)//遍历长方形
{
for(int j=1;j<=maxn;j++)
{
if(i!=j)
{
sum2+=(n-i+1)*(m-j+1);
}
}
}
cout<<sum1<<" "<<sum2;
return 0;
}
总结
暴力模拟题
P2956 [USACO09OCT]The Robot Plow G
题意
计算一共犁了多少块地
思路
- 利用二维数组标记是否已经犁过
- 遍历所有地计算犁过的数量
坑点
- 无
代码
#include<bits/stdc++.h>
using namespace std;
int a[550][550]={0};
int main()
{
int n,m,k;
cin>>n>>m>>k;
while(k--)
{
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
for(int i=x1;i<=x2;i++)//遍历犁过的地
{
for(int j=y1;j<=y2;j++)
{
a[i][j]=1;
}
}
}
int ans=0;
for(int i=1;i<=n;i++)//计算一共犁的地数
{
for(int j=1;j<=m;j++)
{
if(a[i][j]==1)
{
ans++;
}
}
}
cout<<ans;
return 0;
}
总结
简单模拟题
P1359 租用游艇
题意
计算从1到n最少需要用的钱
思路
- 从1到2依次往后计算每次都寻找最小值直到算到1到n
坑点
- 初值要尽量大
代码
#include<bits/stdc++.h>
using namespace std;
int a[220][220];//记录两地间的费用
int dp[500];//记录到i的费用
const int N=1e5+10;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
cin>>a[i][j];
}
dp[i]=N;//将初值付大
}
dp[1]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<i;j++)
{
dp[i]=min(dp[i],dp[j]+a[j][i]);
}
}
cout<<dp[n];
return 0;
}
总结
简单dp的应用
P2242 公路维修问题
题意
计算最小长度和
思路
- 贪心,可以分成M段,要使长度和最小那中间分隔的要最大
- 先计算总长度,再分别计算各个点之间的距离从大到小排序
- 尽可能的将大的减去
坑点
- 长度和相减后要加1
代码
#include<bits/stdc++.h>
using namespace std;
int a[15500];
int b[15500];//记录相隔的距离
int main()
{
int n,m;
cin>>n>>m;
int ans;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
ans=a[n]-a[1]+1;//为初始总长度
for(int i=1;i<=n;i++)
{
b[i]=a[i+1]-a[i];
}
sort(b+1,b+1+n,greater<int>());//将距离从大到小排序
for(int i=1;i<m;i++)
{
ans-=b[i]-1;//依次减去最大的m-1个
}
cout<<ans;
return 0;
}
总结
排序贪心题
P1199 [NOIP2010 普及组] 三国游戏
题意
判断小涵是否可以获胜并输出默契值
思路
- 要使小涵获胜他的默契值要比计算机大
- 最大的默契值一定是被计算机破坏的,那小涵手里的是第二大的默契值
坑点
- 寻找到如何避开计算机的规律使小涵获胜
代码
#include<bits/stdc++.h>
using namespace std;
int a[550][550];
int main()
{
int n;
cin>>n;
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
cin>>a[i][j];
a[j][i]=a[i][j];//记录i和j的默契值
}
}
for(int i=1;i<=n;i++)//寻找每个人与其他人的默契值最大的第二大默契值
{
sort(a[i]+1,a[i]+1+n,greater<int>());
ans=max(ans,a[i][2]);
}
cout<<1<<endl;
cout<<ans<<endl;
return 0;
}
总结
贪心加博弈论