https://www.luogu.com.cn/problem/P2241
十年OI一场空,不开 long long见祖宗。 记得开long long
首先矩形的个数: 十分的容易理解。矩形的个数减去正方形的个数就是长方形的个数。
下图载自洛谷题解的灬Amiya灬大佬
那么正方形的个数如何求? 我看了洛谷的题解,可能是我太笨了,实在想不出为啥那样算。
于是自己写了一个比较笨但是十分易懂的方法。
例:
#include
#include
using namespace std;
int nx[5005],mx[5005];
long long int sum;
unsigned long long int sum1;
int main(void)
{
long long int n,m;cin>>n>>m;
for(int i=1;i<=n;i++) nx[i]=n-i+1;//初始化每一个边长的个数
for(int i=1;i<=m;i++) mx[i]=m-i+1;//初始化每一个边长的个数
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(i==j)//说明是正方形
sum+=nx[i]*mx[j];
}
}
sum1=(n*(n+1)/2)*(m*(m+1)/2)-sum;
cout<<sum<<" "<<sum1<<endl;
return 0;
}
https://www.luogu.com.cn/problem/P2089
#include
#include
#include
using namespace std;
int n;
int a[10];
int b[60005][10];
int ans=0;
void dfs(int index)
{
if(index==10)
{
int sum=0;
for(int i=0;i<10;i++) sum+=a[i];
if(sum==n)
{
for(int i=0;i<n;i++) b[ans][i]=a[i];//保存状态
ans++;
}
return;
}
for(int i=1;i<=3;i++)
{
a[index]=i;
dfs(index+1);
}
}
int main(void)
{
cin>>n;
if(n>30||n<10)
{
cout<<0<<endl;
return 0;
}
dfs(0);
cout<<ans<<endl;
for(int i=0;i<ans;i++)
{
for(int j=0;j<10;j++)
cout<<b[i][j]<<" ";
cout<<endl;
}
return 0;
}
https://www.luogu.com.cn/problem/P1618
#include
#include
#include
#include
using namespace std;
int s[9]={1,2,3,4,5,6,7,8,9};
struct node
{
int x,y,z;
}stu;
vector<node>ve;
int main(void)
{
int a,b,c; cin>>a>>b>>c;
do
{
stu.x=s[0]*100+s[1]*10+s[2];
stu.y=s[3]*100+s[4]*10+s[5];
stu.z=s[6]*100+s[7]*10+s[8];
if( (stu.x*b==stu.y*a) && (stu.x*c)==(stu.z*a)) ve.push_back(stu);
}while(next_permutation(s,s+9));
if(!ve.size()) cout<<"No!!!"<<endl;
else for(int i=0;i<ve.size();i++) cout<<ve[i].x<<" "<<ve[i].y<<" "<<ve[i].z<<endl;
return 0;
}
https://www.luogu.com.cn/problem/P1036
#include
#include
#include
#include
using namespace std;
const int N=30;
int a[N];
bool b[N];
int n,k;
int ans;
bool judge(int a)
{
if(a==1) return false;
if(a==2) return true;
int temp=sqrt(a);
for(int i=2;i<=temp;i++)
{
if(a%i==0)
return false;
}
return true;
}
void dfs(int start,int sum)
{
if(sum==k)
{
int s=0;
for(int i=0;i<n;i++)
{
if(b[i])
{
s+=a[i];
}
}
if(judge(s))
ans++;
return;
}
for(int i=start;i<n;i++)
{
if(!b[i])
{
b[i]=true;
dfs(i,sum+1);
b[i]=false;
}
}
}
int main(void)
{
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i];
dfs(0,0);
cout<<ans<<endl;
return 0;
}
https://www.luogu.com.cn/problem/P1157
#include
#include
using namespace std;
int n,r;
bool a[25];
void dfs(int start,int sum)
{
if(sum==r)
{
for(int i=0;i<=n;i++)
if(a[i]) printf("%3d",i);
cout<<endl;
return;
}
for(int i=start;i<=n;i++)
{
a[i]=true;
dfs(i+1,sum+1);
a[i]=false;
}
}
int main(void)
{
cin>>n>>r;
dfs(1,0);
return 0;
}
https://www.luogu.com.cn/problem/P1706
#include
#include
#include
using namespace std;
int a[9]={1,2,3,4,5,6,7,8,9};
int main(void)
{
int n; cin>>n;
do
{
for(int i=0;i<n;i++) printf("%5d",a[i]);
cout<<endl;
}while(next_permutation(a,a+n));
return 0;
}
#include
#include
#include
using namespace std;
int a[9];
bool b[10];
int n;
void dfs(int index)
{
if(index==n)
{
for(int i=0;i<n;i++) printf("%5d",a[i]);
cout<<endl;
return;
}
for(int i=1;i<=n;i++)
{
if(!b[i])
{
b[i]=true,a[index]=i;
dfs(index+1);
b[i]=false;
}
}
}
int main(void)
{
cin>>n;
dfs(0);
return 0;
}
https://www.luogu.com.cn/problem/P1088
不要被N吓到,关键点在于m,m<=100。所以直接全排列
#include
#include
#include
using namespace std;
int a[100005];
int main(void)
{
int n,m; cin>>n>>m;
for(int i=0;i<n;i++) cin>>a[i];
while(m--) next_permutation(a,a+n);
for(int i=0;i<n;i++) cout<<a[i]<<" ";
return 0;
}
https://www.luogu.com.cn/problem/P3392
数据范围很小,直接暴力枚举两个分割线就行了。
#include
#include
#include
#include
using namespace std;
string str[55];
int ans,sum=1e9;
int main(void)
{
int n,m; cin>>n>>m;
for(int i=0;i<n;i++) cin>>str[i];
for(int i=0;i<n-2;i++)//分割线1
{
for(int j=i+1;j<n-1;j++)//分割线2
{
ans=0;
for(int a1=0;a1<=i;a1++)
{
for(int a11=0;a11<m;a11++)//白
{
if(str[a1][a11]!='W') ans++;
}
}
for(int a2=i+1;a2<=j;a2++)
{
for(int a22=0;a22<m;a22++)//蓝
{
if(str[a2][a22]!='B') ans++;
}
}
for(int a3=j+1;a3<n;a3++)
{
for(int a33=0;a33<m;a33++)//红
{
if(str[a3][a33]!='R') ans++;
}
}
sum=min(ans,sum);
}
}
cout<<sum<<endl;
}
https://www.luogu.com.cn/problem/P3654
#include
#include
#include
#include
using namespace std;
int dx[2]={0,1};//向右,或向下走。避免回去重复
int dy[2]={1,0};
string a[205];
bool hush[205][205];
int ans;
int n,m,k;
void dfs(int x,int y)
{
for(int i=0;i<2;i++)
{
int tempx=x+dx[i];
int tempy=y+dy[i];
if(tempx>=0&&tempx<n&&tempy>=0&&tempy<m&&a[tempx][tempy]=='.')
{
int j;
int tempx=x;
int tempy=y;
for(j=1;j<=(k-1);j++)
{
tempx=tempx+dx[i];
tempy=tempy+dy[i];
if(tempx<0||tempx>=n||tempy<0||tempy>=m||a[tempx][tempy]!='.')
break;
}
if(j==k) ans++;
}
}
}
int main(void)
{
cin>>n>>m>>k;
for(int i=0;i<n;i++) cin>>a[i];
if(k==1) //特殊情况
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i][j]=='.') ans++;
cout<<ans<<endl;
return 0;
}
if(n==1&&m==1)
{
if(a[0][0]=='.') cout<<1<<endl;
else cout<<0<<endl;
return 0;
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(a[i][j]=='.') dfs(i,j);
cout<<ans<<endl;
return 0;
}
https://www.luogu.com.cn/problem/P1149
#include
#include
using namespace std;
int a[10]={6,2,5,5,4,5,6,3,7,6};
// 0 1 2 3 4 5 6 7 8 9
int sum[2005];
int ans;
int main(void)
{
int n; cin>>n;
sum[0]=6;
for(int i=1;i<=2000;i++)//计算前2000的数字各自需要的火柴数
{
int temp=i;
while(temp)
{
int t=temp%10;
sum[i]+=a[t];
temp/=10;
}
}
for(int i=0;i<=1000;i++)
{
for(int j=0;j<=1000;j++)
{
int temp=n-sum[i]-sum[j]-4;
if(sum[i+j]==temp) ans++;
}
}
cout<<ans<<endl;
return 0;
}
https://www.luogu.com.cn/problem/P3799
题解:部分载自: zhangziyi_xshsnoi
首先,我们要知道的是,如果要选4根火柴可以组成等边三角形。
那么必须 有两根是一样长的,且作为边长,另外两根的和等于边长,
那么另外两根有两种情况:
代码如下:
#include
#include
#include
using namespace std;
int a[5005];
int start=1e9,endx=-1e9;//记录最小的数,和最大的数
int mod=1e9+7;
long long int ans;
int main(void)
{
int n,number; cin>>n;
for(int i=0;i<n;i++) scanf("%d",&number),a[number]++,start=min(start,number),endx=max(endx,number);
for(int i=start;i<=endx;i++)
{
if(a[i]>=2)//有两根是一样的,作为边长
{
for(int j=start;j<=i/2;j++)
{
if((i-j)!=j)//另外两条边是不同的。
{
ans+=(long)a[i]*(a[i]-1)/2*a[j]*a[i-j]%mod;
}
else//另外两条边是想同的。
{
ans+=(long)a[i]*(a[i]-1)/2*a[j]*(a[j]-1)/2%mod;
}
}
ans=ans%mod;
}
}
cout<<ans<<endl;
return 0;
}
https://www.luogu.com.cn/problem/P2392
#include
#include
#include
#include
using namespace std;
int n;
int s[5];
int a[4][25];
int ans=999999999;
int L,R;
int cnt;
void dfs(int index,int sum)//index当前的个数, sum当前的科目的下标
{
if(index==s[sum])//做完了
{
ans=min(ans,max(L,R));
return;
}
L+=a[sum][index];//左
dfs(index+1,sum);
L-=a[sum][index];
R+=a[sum][index];//右
dfs(index+1,sum);
R-=a[sum][index];
}
int main(void)
{
cin>>s[0]>>s[1]>>s[2]>>s[3];
for(int i=0;i<4;i++)
{
for(int j=0;j<s[i];j++)
{
cin>>a[i][j];
}
}
for(int i=0;i<4;i++)
{
ans=999999;//初始化
L=R=0;//初始化
dfs(0,i);
cnt+=ans;//总的时间
}
cout<<cnt<<endl;
return 0;
}
https://www.luogu.com.cn/problem/P2036
#include
#include
#include
#include
using namespace std;
//pairp;
int n;
struct node
{
int a;
int b;
}Node[15];
bool m[15];
int ans=999999;
void dfs(int index)
{
if(index==n)
{
int sum1=1;
int sum2=0;
for(int i=0;i<n;i++)
{
if(m[i])
{
sum1*=Node[i].a;
sum2+=Node[i].b;
}
}
int sum=abs(sum1-sum2);
if(sum2!=0)
ans=min(ans,sum);
return;
}
m[index]=true;
dfs(index+1);
m[index]=false;
dfs(index+1);
}
int main(void)
{
cin>>n;
for(int i=0;i<n;i++) cin>>Node[i].a>>Node[i].b;
dfs(0);
cout<<ans;
return 0;
}