count=0
for i in range(2001,2022):
for j in range(1,13):
if j==4 or j==6 or j==9 or j==11:
n=31
elif j==2:
n=29
else:
n=32
for k in range(1,n):
sum=0
for a in str(i):
sum=sum+int(a)
for b in str(j):
sum=sum+int(b)
for c in str(k):
sum=sum+int(c)
if sum==9 or sum==16 or sum==25:
count=count+1
print(count)
需要注意的是此代码没有考虑闰年的情况,在01年到21年中,一共有5个闰年,分别是2004,2008,2012,2016,2020,计算之后会发现,多加的那五天都不是完全日期。
#include
#include
using namespace std;
int n;
int main()
{
cin>>n;
int t=sqrt(n);
double d;
for(int a=0; a<t; a++)
{
for(int b=a; b<t; b++)
{
for(int c=b; c<t; c++)
{
d=sqrt(n-a*a-b*b-c*c);
if(d==int(d)) //恰好减完
{
cout<<a<<" "<<b<<" "<<c<<" "<<d;
return 0;
}
}
}
}
return 0;
}
题意:
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法。
A
9 6
4 8
3 7 5 2
这样的排法可能会有很多。如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。
#include
using namespace std;
int ans;
int arr[10];
int st[10];
void dfs(int len)
{
if(len==9)
{
if(arr[0]+arr[1]+arr[2]+arr[3]==arr[3]+arr[4]+arr[5]+arr[6]&&arr[3]+arr[4]+arr[5]+arr[6]==arr[6]+arr[7]+arr[8]+arr[0])
{
ans++;
}
return;
}
for(int i=1; i<=9; i++)
{
if(!st[i])
{
arr[len]=i;
st[i]=1;
dfs(len+1);
st[i]=0;
}
}
}
int main()
{
dfs(0);
cout<<ans/6<<endl;//去掉对称和旋转之后重复的
return 0;
}
#include
#include
#include
#include
using namespace std;
struct Node
{
int x;
int y;
}node[450];
vector<int> v;
set<vector<int>> q;
int main()
{
int cnt=0;
for(int i=0;i<20;i++)//存
{
for(int j=0;j<21;j++)
{
node[cnt].x=i;
node[cnt++].y=j;
}
}
for(int i=0;i<cnt;i++)//遍历
{
for(int j=i;j<cnt;j++)
{
if(node[i].x==node[j].x&&node[i].y==node[j].y) continue;
int a=node[j].y-node[i].y;
int b=node[j].x-node[i].x;
int c=node[i].x*node[j].y-node[i].y*node[j].x;
int gcd=__gcd(a,__gcd(b,c));
v.push_back(a/gcd);
v.push_back(b/gcd);
v.push_back(c/gcd);
q.insert(v);
v.clear();
}
}
cout<<q.size()<<endl;
return 0;
}
#include
#include
using namespace std;
const int INF=1e9;
int d[2022][2022];
void floyd()
{
for(int k=1;k<=2021;k++)
{
for(int i=1;i<=2021;i++)
{
for(int j=1;j<=2021;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
}
}
int main()
{
for(int i=1;i<=2021;i++)
{
for(int j=1;j<=2021;j++)
{
if(abs(i-j)<=21)
{
d[i][j]=i*j/__gcd(i,j);
}
else d[i][j]=INF;
}
}
floyd();
cout<<d[1][2021]<<endl;
return 0;
}
#include
#include
#include
#include
using namespace std;
int g[2030][2030];
int dist[2030];
int st[2030];
int d()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<2021;i++)
{
int t=-1;
for(int j=1;j<=2021;j++)
{
if(!st[j]&&(t==-1||dist[j]<dist[t])) t=j;
}
st[t]=1;
for(int j=1;j<=2021;j++)
{
dist[j]=min(dist[j],dist[t]+g[t][j]);
}
}
if(dist[2021]==0x3f3f3f3f) return -1;
else return dist[2021];
}
int main()
{
memset(g,0x3f,sizeof g);
for(int i=1;i<=2021;i++)
{
for(int j=1;j<=2021;j++)
{
if(abs(i-j)<=21)
{
g[i][j]=i*j/__gcd(i,j);
g[j][i]=g[i][j];
}
}
}
printf("%d",d());
return 0;
}
dp法:
#include
using namespace std;
const int M=200020,B=M/2;//B为偏移量,因为数组下标不能为负数
int n,m;
int w[110];
bool f[110][M];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i];
m+=w[i];
}
f[0][B]=true;//初始化,当一个也不选时,这种情况成立
for(int i=1;i<=n;i++)
{
for(int j=-m;j<=m;j++)
{
f[i][j+B]=f[i-1][j+B];//不选时,可以直接从i-1过渡到i
if(j-w[i]>=-m) f[i][j+B]|=f[i-1][j-w[i]+B];//砝码放右边的情况
if(j+w[i]<=m) f[i][j+B]|=f[i-1][j+w[i]+B];//砝码放左边的情况
}
}
int cnt=0;
for(int i=1;i<=m;i++)//从重量为1到m的区间内去选择
{
if(f[n][i+B]) cnt++;
}
cout<<cnt<<endl;
return 0;
}
贴大佬做法:
#include
#include
using namespace std;
const int N = 105, M = 100005;
int g[N], n;
bitset<M> S;
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i ++ ){
scanf("%d", &g[i]);
}
S[0] = 1;
for(int i = 0; i < n; i ++ ){
S |= S << g[i];
}
for(int i = 0; i < n; i ++ ){
S |= S >> g[i];
}
cout << S.count() - 1 << endl;
return 0;
}
dfs(得一半分):
#include
using namespace std;
int n;
int w[100010];
int st[100010];
int cnt;
void dfs(int k,int m)
{
if(k>n)
{
if(!st[m]&&m>0)
{
cnt++;
st[m]=1;
}
return;
}
else
{
dfs(k+1,m);//不选
dfs(k+1,m+w[k]);//右
dfs(k+1,m-w[k]);//左
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>w[i];
dfs(0,0);
cout<<cnt<<endl;
return 0;
}
统计不符合条件的
2个:15
3个:17
4个:7
5个:2
128-7-15-17-7-2=80
法二:(dfs+并查集)
#include
using namespace std;
const int N = 10;
int use[N], ans, e[N][N], p[N];
void init()
{
/*
a b c d e f g
1 2 3 4 5 6 7
*/
e[1][2] = e[1][6] = 1;
e[2][1] = e[2][7] = e[2][3] = 1;
e[3][2] = e[3][4] = e[3][7] = 1;
e[4][3] = e[4][5] = 1;
e[5][4] = e[5][6] = e[5][7] = 1;
e[6][1] = e[6][5] = e[6][7] = 1;
e[7][2] = e[7][3] = e[7][5] = e[7][6] = 1;
}
int find(int x)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void dfs(int d)
{
if(d > 7)
{
//并查集判是否在同一集合
for(int i = 1; i <= 7; i++) p[i] = i;
for(int i = 1; i <= 7; i++) //遍历所有边集
{
for(int j = 1; j <= 7; j++)
{
if(e[i][j] && use[i] && use[j]) //i和j相邻并且都亮着
{
if(find(i)!=find(j)) p[find(i)]=find(j);//如果不在同一集合,合并
}
}
}
int k = 0;
for(int i = 1; i <= 7; i++)
if(use[i] && p[i] == i) k++;
if(k == 1) ans++;//如果所有亮灯都属于同一个集合
return;
}
use[d] = 1;//打开d这个灯,继续开关下一个灯
dfs(d + 1);
use[d] = 0;//关闭d这个灯,继续开关下一个灯
dfs(d + 1);
}
int main()
{
init();
dfs(1);
cout << ans;
}