目录
题目来源:
第一题:高斯日记(日期计算)
#include<iostream>
using namespace std;
int months[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
bool is_leap(int year)
{
return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0));
}
int main()
{
int year = 1777;
int month = 4;
int day = 30;
int T = 8112;
while (T--)
{
day++;
if (month == 2)
{
if (is_leap(year)) months[2] = 29;//如果是闰年
}
if (day > months[month])//如果天数已经大于该月的天数时
{
if (month == 12)//如果该月是12月,那么就++年
{
year++;
month = 1;//月份重新变为1
day = 1;
}
else month++, day = 1;//否则只是月份++
}
months[2] = 28;//还原
}
printf("%d-%02d-%02d\n", year, month, day);//1799-07-16
return 0;
}
第二题:马虎的算式(全排列)
解析:
按题目所给形式模拟即可
#include<iostream>
using namespace std;
int main()
{
int ans = 0;
for(int a = 1; a <= 9; a++)
{
for(int b = 1; b <= 9; b++)
{
if(a!=b)
for(int c =1; c <= 9; c++)
{
if(c!=b&&c!=a)
for(int d =1; d <= 9; d++)
{
if(d!=c&&d!=b&&d!=a)
for(int e =1; e <= 9; e++)
{
if(e!=d&&e!=c&&e!=b&&e!=a)
{
int left = (a*10+b) * (c*100+d*10+e);
int right = (a*100+d*10+b) * (c*10+e);
if(left == right)
{
ans++;
}
}
}
}
}
}
}
cout << ans;
return 0;
}
第三题:第39级台阶(dfs)
解析:
dfs:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int ans;
// total表示当前走过的台阶数量,step表示当前的步数
void dfs(int total, int step)
{
// 超出边界
if(total > 39) return;
if(total == 39)
{
// 步数为偶数,计数器加一
if(step % 2 == 0) ans ++;
return ;
}
// 每次迈步都有两种选择
dfs(total + 1, step + 1);
dfs(total + 2, step + 1);
}
int main()
{
dfs(0, 0);
cout << ans << endl;
return 0;
}
dp:
#include <iostream>
using namespace std;
int f[40][40];
int main()
{
f[1][1] = 1;
f[1][2] = 0;
f[2][1] = 1;
f[2][2] = 1;
for (int i = 3; i <= 39; i ++)
{
f[i][1] = f[i - 1][2] + f[i - 2][2];
f[i][2] = f[i - 1][1] + f[i - 2][1];
}
cout << f[39][2] << endl;
return 0;
}
第四题:黄金连分数(递推+大数运算)
黄金连分数(斐波那契数列、大数运算)正确解法_WinOneKey的博客-CSDN博客_黄金连分数
第五题:前缀判断(枚举)
char *prefix(char *haystack_start,char *needle_start)
{
char *haystack=haystack_start;
char *needle=needle_start;
while(*haystack&&*needle)
{
if(_____________________) return NULL; //填空位置
}
if(*needle) return NULL;
return haystack_start;
}
解析:
只有前面有一个不相等,那么前缀就不相等,同时注意还需要往后推进,也就是++
答案为:*(haystack++)!=*(needle++)
第六题:三部排序
#include <stdio.h>
void sort3p(int *x,int len)
{
int p=0;
int left=0;
int right=len-1;
int t;
while(p<=right)
{
if(x[p]<0)
{
t=x[left]; x[left]=x[p]; x[p]=t; left++; p++;
}
else if(x[p]>0)
{
t=x[right]; x[right]=x[p]; x[p]=t; right--;
}
else
{
_______________________//填空位置
}
}
}
解析:
代码已经写得很清楚了:对p[x]分为以下三种情况
那么根据题意描述可知p相当于i,就是一个迭代的工具而已,所以要让p++,然后else的情况肯定是对应着0的,所以答案为:
x[p++]=0
第七题:错误票据
解析:
因为题目说:断号不可能发生在最小值和最大值,因此就以它们两作为边界,用哈希表记录频数即可
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
int ha[N];
int main()
{
int n;
cin>>n;
int minv=INF;
int maxv=-INF;
int tp;
while(cin>>tp)
{
if(tp<minv) minv=tp;
if(tp>maxv) maxv=tp;
ha[tp]++;
}
int ans1=0,ans2=0;
for(int i=minv;i<=maxv;i++)
{
if(ha[i]==0) ans1=i;
if(ha[i]==2) ans2=i;
}
cout<<ans1<<" "<<ans2<<endl;
return 0;
}
第八题:买不到的数目(打表找数学规律)
打表:
#include<iostream>
using namespace std;
int n, m;
int main()
{
cin >> n >> m;
int k = n * m;
while (k)
{
int t = k;
while (t % m != 0 && t - n > 0) t -= n;
//条件1 条件2 条件3
if (t % m != 0 && k % n != 0 && k % m != 0)
{
cout << k << endl;
break;
}
k--;
}
return 0;
}
正解:
#include<iostream>
using namespace std;
int n,m;
int main()
{
cin>>n>>m;
cout<<(n-1)*(m-1)-1<<endl;
return 0;
}
第九题:剪格子(困难)
活动 - AcWing
第十题:大臣的旅费(树的直径+dfs)
vector模拟链表:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std;
const int N = 100010;
int n;
struct Edge
{
int id, w;//指向的那条边,和这条边的边长
};
vector<Edge> h[N];
int dist[N];
void dfs(int u, int father, int distance)
{
dist[u] = distance;//记录长度
for (auto node : h[u])//想象成单链表
{
if (node.id != father)//保证不会往回走,保证向下走
dfs(node.id, u, distance + node.w);//当前节点,u则为当前节点的父亲,距离增加
}
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n - 1; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
h[a].push_back({ b,c });
h[b].push_back({ a,c });
}
dfs(1, -1, 0);//第一次传参:当前节点,当前节点的父亲,当前节点到父节点的距离
int u = 1;
for(int i=1;i<=n;i++)
if (dist[i] > dist[u])//寻找从1号点到最远能到的路径距离
{
u = i;
}
dfs(u, -1, 0);//上述的最远的能到的距离作为头,从新开始寻找离它的最远距离
for(int i=1;i<=n;i++)
if (dist[i] > dist[u])//同理
{
u = i;
}
int s = dist[u];//u到最远的距离
printf("%lld\n", s * 10 + s * (s + 1ll) / 2);
return 0;
}
数组模拟链表:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010, M = 200010;
int n;
int h[N], e[M], w[M], ne[M], idx;
int dist[N];
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
void dfs(int u, int father, int distance)
{
dist[u] = distance;
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (j != father)
dfs(j, u, distance + w[i]);
}
}
int main()
{
scanf("%d", &n);
memset(h, -1, sizeof h);
for (int i = 0; i < n - 1; i ++ )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}
dfs(1, -1, 0);
int u = 1;
for (int i = 2; i <= n; i ++ )
if (dist[u] < dist[i])
u = i;
dfs(u, -1, 0);
for (int i = 1; i <= n; i ++ )
if (dist[u] < dist[i])
u = i;
printf("%lld\n", dist[u] * 10 + (dist[u] + 1ll) * dist[u] / 2);
return 0;
}
作者:yxc
链接:https://www.acwing.com/activity/content/code/content/178927/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。