473. 火柴拼正方形

你将得到一个整数数组 matchsticks ,其中 matchsticks[i] 是第 i 个火柴棒的长度。你要用 所有的火柴棍 拼成一个正方形。你 不能折断 任何一根火柴棒,但你可以把它们连在一起,而且每根火柴棒必须 使用一次 。

如果你能使这个正方形,则返回 true ,否则返回 false 。

思路:

首先一定要注意到这个题要所有的火柴都要用上,那么所有火柴的长度一定是4的倍数,即sum%4==0

那么每一跟火柴的长度 len=sum/4

对于每条边,我都试着把一根火柴放进去,如果这条边的长度没有超过len,那么就满足,枚举下一根火柴。

如果大于len则返回FALSE

  1. class Solution {
  2. public:
  3. bool dfs(int index,vector<int> mat,vector<int> &edges,int len){
  4. if(index==mat.size()) return true;
  5. for(int i=0;i<edges.size();i++){
  6. edges[i]+=mat[index];
  7. if(edges[i]<=len&&dfs(index+1,mat,edges,len)){
  8. return true;
  9. }
  10. edges[i]-=mat[index];//恢复现场
  11. }
  12. return false;
  13. }
  14. bool makesquare(vector<int>& mat) {
  15. //题目的意思是用所有的火柴,合成正方形
  16. int sum=0;
  17. for(int i=0;i<mat.size();i++){
  18. sum+=mat[i];
  19. }
  20. int len=sum/4;
  21. if(sum%4!=0) return false;
  22. sort(mat.begin(),mat.end(),[&](int a,int b){
  23. return a>b;
  24. });
  25. vector<int> edges(4);
  26. return dfs(0,mat,edges,len);
  27. }
  28. };

类似的题目:

派蒙游戏世界对旅行荧妹很不友好

题目大意:

派蒙最近总是和旅行者在玩游戏,这个游戏共有 nnn 轮,在第 iii 轮获胜的人会获得 iii 分,没有平局。

现在给出派蒙和旅行者的得分,请问是否有一种方案符合当前得分。

换句话说就是 给定两个数 a,b 问是否存在使用1~n的数组合,和为a和b。

思路:

和上面的题目类似;从大的开始枚举如果没有超过需要的和,那么就可以放进去。就是能放就放的原则。

不能放就跳过。

在这个题目一定有解的。

代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define int long long
  4. signed main(){
  5. int a,b;
  6. cin>>a>>b;
  7. int n=sqrt((a+b)*2);
  8. if((n+1)*n!=(a+b)*2){
  9. cout<<"NO"<<endl;
  10. return 0;
  11. }
  12. cout<<"YES"<<endl;
  13. cout<<n<<endl;
  14. for(int i=n;i>=1;i--){
  15. if(a>=i) {
  16. a-=i;
  17. cout<<i<<" ";
  18. }
  19. }
  20. return 0;
  21. }