我发现我似乎越来越喜欢这种一道题有多种解法,然后一个个去看,让自己大为震撼的感觉哈哈哈哈哈!当然,这道题目前提不是很难!
填空题
第一题:门牌制作
参考答案:624 写法一:
#include<bits/stdc++.h>
using namespace std;
int main()
{
freopen("out.txt","w",stdout);
for(int i=1;i<=2020;i++)
printf("%d",i);
return 0;
}
我们把他打表打出来,然后全选复制到word文档里面。
ctrl+F,寻找2,答案是624 写法二:当然我们也可以整数分解
#include <iostream>
using namespace std;
int ans;
void check(int n)
{
while(n)
{
int t = n % 10;
if(t == 2) ans ++;
n /= 10;
}
}
int main()
{
for (int i = 1; i <= 2020; i ++)
check(i);
cout << ans << endl;
return 0;
}
第二题:既约分数
参考答案:2481215 太恐怖了,我就是没有考虑1/1的情况,差一点这道题目就白写了!!!呜呜呜
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b)
{
return a%b==0?b:gcd(b,a%b);
}
int main()
{
int res=0;
for(int i=1;i<=2020;i++)
for(int j=i+1;j<=2020;j++)
if(gcd(j,i)==1)res++;
cout<<res*2+1<<endl;
return 0;
}
第三题:蛇形填数
参考答案:761 代码就是硬模拟,一次往左下,一次往右上 写法一:反正我觉得这个就是很考察思维,我是感觉很难对于我来说,还得多练
#include <bits/stdc++.h>
using namespace std;
int a[50][50],cnt=1;
int main()
{
for(int i = 1 ; i <= 40; i++)
{
if(i % 2==1 )
{
for(int x = i, y = 1; x >= 1 && y <= i; x--, y++)
a[x][y] = cnt++;
}
else
{
for(int x = 1, y = i; x <= i && y >= 1; x++, y--)
a[x][y] = cnt++;
}
}
printf("%d\n", a[20][20]);
return 0;
}
写法二:找规律,牛逼哄哄 对角线上的数分别为 1、5、13、25……
#include <iostream>
using namespace std;
int main()
{
int w = 4, ans = 1;
for (int i = 1; i <= 19; i ++)
{
ans += w;
w += 4;
}
cout << ans << endl;
return 0;
}
第四题:跑步锻炼
参考答案:8879
写法一:工具得利用起来哇
#include<bits/stdc++.h>
using namespace std;
int t[12]={31,29,31,30,31,30,31,31,30,31,30};
int main()
{
int ans=0;
ans+=2+1+2;
int res=7579;
res-=3;
int k=res/7;
ans+=k+res;
int sum=0;
for(int i=0;i<=20;i++)
{
for(int j=0;j<12;j++)
{
if(i==20&&j==9)break;
if(j==1&&i%4==0)
sum+=t[j];
else sum+=t[j]+1;
if((sum+5)%7!=0)ans++;
}
}
cout<<ans<<endl;
return 0;
}
写法二:这个写法和写法一类似哦! 解题思路: 1、用 0 ~ 6 来代表 周一 至 周日; 2、用 sum 来代表 2000年1月1日 至 某年某月某日 所经过的天数; 3、由于 2000年1月1日 是周六,那么用 (sum + 5) % 7 就能表示 某年某月某日 是星期几; 4、因为 2020年10月1日 未处理,所以最后 ans += 2;
#include <iostream>
using namespace std;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool is_leap(int year)
{
return year % 400 == 0 || year % 4 == 0 && year % 100 != 0;
}
int get_day(int year, int month)
{
if(month == 2) return 28 + is_leap(year);
return days[month];
}
int main()
{
int sum = 0, ans = 0;
for (int i = 2000; i <= 2019; i ++)
for (int j = 1; j <= 12; j ++)
for (int k = 1; k <= get_day(i, j); k ++)
{
int weekday = (sum + 5) % 7;
if(k == 1 || weekday == 0) ans += 2;
else ans ++;
sum ++;
}
for (int j = 1; j <= 9; j ++)
for (int k = 1; k <= get_day(2020, j); k ++)
{
int weekday = (sum + 5) % 7;
if(k == 1 || weekday == 0) ans += 2;
else ans ++;
sum ++;
}
cout << ans + 2 << endl;
return 0;
}
第五题:七段码
参考答案:80 写法一: 让我感受到,这的是方法千千万啊!
写法二:位运算 打表打出来之后再一个个的数。
#include <iostream>
using namespace std;
int main()
{
freopen("out.txt","w",stdout);
int cnt = 1;
for (int x = 1; x <= 127; x ++)
{
cout << "====" << cnt ++ << "====" << endl;
for (int i = 0; i < 7; i ++)
{
if(i == 0)
{
if(x >> i & 1) cout << " --";
cout << endl;
}
if(i == 1)
{
if(x >> i & 1) cout << '|';
else cout << " ";
}
if(i == 2)
{
if(x >> i & 1) cout << " |";
cout << endl;
}
if(i == 3)
{
if(x >> i & 1) cout << " --";
cout << endl;
}
if(i == 4)
{
if(x >> i & 1) cout << '|';
else cout << " ";
}
if(i == 5)
{
if(x >> i & 1) cout << " |";
cout << endl;
}
if(i == 6)
{
if(x >> i & 1) cout << " --";
cout << endl;
}
}
cout << endl;
}
return 0;
}
写法三:DFS+并查集
#include <iostream>
using namespace std;
const int N = 10;
int ans;
int p[N];
bool st[N];
int e[N][N];
int find(int x)
{
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
void dfs(int u)
{
if(u == 8)
{
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] && st[i] && st[j])
p[find(i)] = find(j);
int cnt = 0;
for (int i = 1; i <= 7; i ++)
if(st[i] && p[i] == i)
cnt ++;
if(cnt == 1) ans ++;
return;
}
st[u] = 1;
dfs(u + 1);
st[u] = 0;
dfs(u + 1);
}
int main()
{
e[1][2] = e[1][6] = 1;
e[2][1] = e[2][7] = e[2][3] = 1;
e[3][2] = e[3][7] = e[3][4] = 1;
e[4][3] = e[4][5] = 1;
e[5][4] = e[5][7] = e[5][6] = 1;
e[6][1] = e[6][7] = e[6][5] = 1;
e[7][2] = e[7][3] = e[7][5] = e[7][6] = 1;
dfs(1);
cout << ans << endl;
return 0;
}
编程题
第六题:成绩统计
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int hg=0,yx=0;
int x;
for(int i=0;i<n;i++)
{
cin>>x;
if(x>=85){yx++;hg++;}
else if(x>=60)hg++;
}
int m=1.0*hg/n*100+0.5;
int k=1.0*yx/n*100+0.5;
printf("%d%%\n%d%%\n",m,k);
return 0;
}
第七题:回文日期
解题思路: 1、我们就枚举年份a,然后再把它翻转过来为b,那么a+b为回文数。 2、用substr来分理出月份和天数,在判断月份和天数是否合法。
实用函数: 1、stoi(x):将字符串转换为数字; 2、to_string(x):将数字转换为字符串 3、substr(u,len):从第u位开始,截取一段长度为len的字符串
#include<bits/stdc++.h>
using namespace std;
int days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int year)
{
return year % 400 == 0 || year % 4 == 0 && year % 100 != 0;
}
int get_day(int year, int month)
{
if(month == 2) return 28 + check(year);
return days[month];
}
int main()
{
int n;
cin >> n;
string ans1, ans2;
bool flag1 = false, flag2 = false;
for (int i = n / 10000; i <= 9999; i ++)
{
string a = to_string(i);
string b = a;
reverse(b.begin(), b.end());
if(a + b <= to_string(n)) continue;
int month = stoi(b.substr(0, 2));
int day = stoi(b.substr(2, 2));
if(month < 1 || month > 12) continue;
if(day < 1 || day > get_day(i, month)) continue;
string s1 = a.substr(0, 2);
string s2 = a.substr(2, 2);
if(!flag1) ans1 = a + b, flag1 = true;
if(!flag2 && s1 == s2 && s1[0] != s1[1]) ans2 = a + b, flag2 = true;
if(flag1 && flag2) break;
}
cout << ans1 << endl;
cout << ans2 << endl;
return 0;
}
第八题:字串分值和
哈希表会破环数组有序性
set与map底层实现是平衡二分搜索树,unordered_set与unordered_map底层实现是哈希表
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 100010, M = 150;
string s;
int Pre[N], Next[N], Idx[M];
int main()
{
cin >> s;
int n = s.size();
s = ' ' + s;
for (int i = 1; i <= n; i ++)
{
Pre[i] = Idx[s[i]];
Idx[s[i]] = i;
}
for (int i = 97; i <= 122; i ++) Idx[i] = n + 1;
for (int i = n; i >= 1; i --)
{
Next[i] = Idx[s[i]];
Idx[s[i]] = i;
}
LL ans = 0;
for (int i = 1; i <= n; i ++)
ans += (LL) (i - Pre[i]) * (Next[i] - i);
cout << ans << endl;
return 0;
}
第九题:平面切分
分析:此题可以通过寻找规律发现, (1)如果重合,则不会增加平面 (2)如果平行,则增加一个平面 (3)如果有一个交点,增加2个平面 (4)有两个交点,增加3个平面
思路:模拟每条线画的过程。 这个暂时只拿了40分,以后回来完善,但是我们可以知道只要暴力模拟就有一定的分!!!
#include<iostream>
#include<set>
using namespace std;
long double num[1001][2];
bool s[1001];
int ans = 1;
pair<long double, long double>p;
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> num[i][0] >> num[i][1];
set<pair<long double, long double> >point;
for (int j = 0; j < i; j++)
{
if (s[j])continue;
if (num[i][0] == num[j][0])
{
if (num[i][1] == num[j][1])
{
s[i] = true;
break;
}
else continue;
}
p.first = (num[i][1] - num[j][1])/ (num[j][1] - num[i][1]);
p.second = (num[i][0] * num[j][1] - num[i][0] * num[j][0]) / (num[j][1] - num[i][1]);
point.insert(p);
}
if (!s[i])
ans += point.size() + 1;
}
cout << ans << endl;
return 0;
}
第十题:字符串排序
大佬!!! 但是这个只能拿70分,后面会来完善的,但是我觉得目前掌握这个思想就已经很不错了!!
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 135, M = 10010;
int f[N][30][N];
int chcnt[N][30];
int mlen[N];
void dp()
{
for (int i = 2; i < N; ++i)
{
int m = 0;
for (int j = 1; j <= 'z' - 'a'; ++j)
{
for (int k = 1; k < i; ++k)
{
if (k > 1) f[i][j][k] = f[i - 1][j][k - 1] + i - k;
else f[i][j][k] = chcnt[i - 1][j - 1] + i - 1;
chcnt[i][j] = max(chcnt[i][j], f[i][j][k]);
}
m = max(m, chcnt[i][j]);
}
mlen[i] = m;
}
}
int main()
{
dp();
int score = 0;
cin >> score;
int beg = 0;
for (int i = 1; i < N; ++i)
if (mlen[i] >= score)
{
beg = i;
break;
}
int curr = 0;
int same = 1;
char last = 'z' + 1;
for (int i = beg; i > 0; --i)
{
int j = 0;
for (; j <= last - 'a'; ++j)
{
if (j == last - 'a') curr -= same;
if (curr + chcnt[i][j] >= score)
{
curr += i - 1;
break;
}
}
if (j == last - 'a') same++;
else
{
last = j + 'a';
same = 1;
}
cout << last;
}
cout << endl;
return 0;
}
|