一、暴力枚举思想:
其实就是直接循环遍历,利用计算机强大的计算性能,也就是俗称的“一个个试”。
二、部分练习&题解:
*2/5/6题较难;
1.NEFU OJ:大乐透
这题需要理清一下思路,然后六重循环完事。不超时是因为数据小,数据较多肯定TLE.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int k;
while(~scanf("%d",&k))
{
if(k==0)
break;
int str[k+1];
for(int i=1;i<=k;i++)
cin>>str[i];
for(int i=1;i<=k;i++)
{
for(int j=i+1;j<=k;j++)
{
for(int x=j+1;x<=k;x++)
{
for(int r=x+1;r<=k;r++)
{
for(int t=r+1;t<=k;t++)
{
for(int l=t+1;l<=k;l++)
{
printf("%d %d %d %d %d %d\n",str[i],str[j],str[x],str[r],str[t],str[l]);
}
}
}
}
}
}
}
return 0;
}
2.NEFU OJ:丑数
这里的代码是nefu_ljw学长的解法,我理解错了题意,用动态数组打了一张错的表(/捂脸)
#include <bits/stdc++.h>
#define min4(a,b,c,d) min(min(a,b),min(c,d))
using namespace std;
int n,p2,p3,p5,p7,a[5850];//定义min4(a,b,c,d),找四个数中的最小值,这里的p1\p2\p3\p4用作数组下标相当于指针
int main()
{
a[1]=1;p2=p3=p5=p7=1;
for(int i=2;i<=5842;i++)//打表5842个丑数
{
a[i]=min4(a[p2]*2,a[p3]*3,a[p5]*5,a[p7]*7);//a[p2]、a[p3]、a[p5]、a[p7]分别为*2、*3、*5、*7的次数
if(a[i]%2==0)p2++;//如第一次进来"a[p2]*2"为四个中的最小值,=2,于是在"p2所指对象发生的变化",
if(a[i]%3==0)p3++;//在把四个“p”看作指针的前提下,p2递增就相当于这个指针下移。
if(a[i]%5==0)p5++;//大佬原话:如果选择的最小值a[i]是乘以了2,则*2的丑数下标位置后移一位
if(a[i]%7==0)p7++;
}
while(cin>>n&&n)
printf("%d\n",a[n]);
return 0;
}
3.NEFU OJ:矩形
这题需要理解题意:“最大最小x、y”在坐标系上确定一个矩形。且本题只用考虑单个完全覆盖就行,不用考虑多个盖一个的情况。
#include <bits/stdc++.h>
using namespace std;
struct stt
{
int minx,maxx,miny,maxy;
}tt[500];
int main()
{
int n,t=0;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
cin>>tt[i].minx>>tt[i].maxx>>tt[i].miny>>tt[i].maxy;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
{
if((tt[i].minx<=tt[j].minx&&tt[i].maxx>=tt[j].maxx)&&(tt[i].miny<=tt[j].miny&&tt[i].maxy>=tt[j].maxy))
{t++;break;}//发现完全覆盖自增就跑
}
if(t)
cout<<t+1<<endl; //由示例可知,需要+1
else
cout<<0<<endl;
t=0;
}
return 0;
}
4.NEFU OJ:楼层编号
就是从1楼道m楼,权位分离,只要有等于t的,自减break;
#include <bits/stdc++.h>
using namespace std;
int main()
{
int m,t,x,k,s;
cin>>m>>t;
s=m;
for(int i=1;i<=s;i++) //需要注意的是这里不能写i<=m,因为m--会改变m的大小!!!
{
k=i;
while(k)
{
x=k%10;
k=k/10;
if(x==t)
{m--;break;}
}
}
cout<<m;
return 0;
}
5.NEFU OJ:比例简化
这题要注意题目“要求在 A′和 B′ 均不大于 L”,“ A′ 和 B′ 互质(两个整数的最大公约数为 1)”,“A′/B′≥ A/B 且 A′/B′-A/B 的值尽可能小”如何用代码实现。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int A,B,L;
int a,b,a1,b1; //ab为A',B',a1b1用于连环相减法的暂时值
double s1,s2,t=10000; //t为两个比值的误差,赋初值为10000是给它一个足够大的值,让其能进行第一次运行
cin>>A>>B>>L;
s1=1.0*A/B;
for(int i=1; i<=L; i++)
for(int j=1; j<=L; j++)
{
s2=1.0*i/j;
if(s2>=s1&&s2-s1<t) //题目的两个条件
{
a=a1=i;
b=b1=j;
t=s2-s1;//为了当循环到更小的差值时再进入if
}
}
while(a1!=b1)
{
if(a1>b1)
a1=a1-b1;
else
b1=b1-a1;
}
a=a/a1; b=b/a1;
cout<<a<<" "<<b;
}
6.NEFU OJ:奶牛碑文
这题让我想起了2019年11月16号的哈理工新生赛,有一题“2019”,与本题条件差不多,求在一串数字中有多少个2019。这种做法需要熟悉。
#include <bits/stdc++.h>
using namespace std;
long cntc,cntco,cntcow; //三个计数器
int main()
{
int n;
string str;
while(~scanf("%d",&n))
{
cin>>str;
for(int i=0;i<n;i++)
{
if(str[i]=='C') cntc++; //当扫到C
if(str[i]=='O') cntco+=cntc; //扫到O
if(str[i]=='W') cntcow+=cntco; //扫到W
}
cout<<cntcow<<endl;
}
return 0;
}
于2020年1月2日在丹青九楼,大一寒假第三天,编辑。(话说昨天元旦整天呆在机房,今天腊八也整天呆机房(/大哭))