门牌制作
遍历求解
#include<iostream>
using namespace std;
int main(){
int cnt=0;
for(int i=1;i<=2020;i++){
int t=i;
while(t){
if(t%10==2) cnt++;
t/=10;
}
}
cout<<cnt;
return 0;
}
即约分数
最大公约数+遍历
#include<iostream>
using namespace std;
int gcd(int a,int b){
return b ? gcd(b,a%b) : a;
}
int main(){
int cnt=0;
for(int i=1;i<=2020;i++){
for(int j=1;j<=2020;j++){
int t=gcd(i,j);
if(t==1) cnt++;
}
}
cout<<cnt;
return 0;
}
蛇形填数
看规律
第(2n-1)行存在(a,a)
用等差数列求和+20就可以算出结果
#include<iostream>
#include<cstdlib>
using namespace std;
int main(){
int n=(1+38)*38/2+20;
cout<<n;
return 0;
}
七段码
我是建图+dfs写的,用map标记是否记录过
#include<iostream>
#include<cstring>
#include<map>
#include<cmath>
using namespace std;
const int N=100;
int h[N],e[N],ne[N],idx;
map<int,int> v;
bool st[10];
int cnt;
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void x(int a,int b){
add(a,b),add(b,a);
}
void dfs(int a,int x){
if(v[x]==0) cnt++,v[x]=1;
for(int i=h[a];i!=-1;i=ne[i]){
int j=e[i];
if(!st[j]){
st[j]=true;
dfs(j,x+j*(int)pow(10,j));
st[j]=false;
}
}
}
int main(){
memset(h,-1,sizeof(h));
int n=7+10+16;
x(1,2),x(2,3),x(3,4),x(4,5),x(5,6),x(1,6),x(7,2),x(7,3),x(7,5),x(7,6);
for(int i=1;i<=7;i++){
st[i]=true;
dfs(i,i*(int)pow(10,i));
st[i]=false;
}
cout<<cnt;
return 0;
}
跑步锻炼
模拟
表示出月初和周一,遍历
#include<iostream>
using namespace std;
int d,w,m,y;
int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int res;
inline void update(){
if(w>7) w=1;
if(y==4 && m==2){
if(d>mon[2]+1){
d=1,m++;
}
}
else if(d>mon[m]) d=1,m++;
if(m>12) m=1,y++;
if(y>4) y=1;
}
int main(){
int n=(365*20+5)+(366-92+1);
d=1,w=6,m=1,y=4;
while(n--){
update();
if(w==1 || (d==1 && w!=1)) res++;
res++;
d++,w++;
}
cout<<res;
return 0;
}
回文日期
思路就是,遍历年份,根据年份确定回文月份(并找出符合格式的),找到后标记、输出
(我写的可能复杂了,有些步骤可以省掉或换掉的)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
int t;
int n;
int m[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int yy, int mm, int dd) {
if(mm >= 1 && mm <= 12) {
if((yy % 400 == 0) || (yy % 4 == 0 && yy % 100 != 0)) {
m[2] = 29;
}
if(m[mm] >= dd && dd != 0)
return true;
else
return false;
}
return false;
}
int main(){
cin>>t;
while(t--){
scanf("%d",&n);
int d=n;
n/=10000;
bool f1=false,f2=false;
int r1,r2;
for(int i=n;i<=9999;i++){
string t1=to_string(i),t2=t1;
reverse(t2.begin(),t2.end());
int a=stoi(t2)/100,b=stoi(t2)%100;
if(!check(i,a,b)) {m[2]=28;continue;}
int dt=stoi(t1+t2);
if(!f1 && dt>d){
r1=dt;
f1=true;
}
if(!f2 && dt>d && a==b){
r2=dt;
f2=true;
}
if(f1 && f2) break;
}
printf("%d\n%d\n",r1,r2);
}
return 0;
}
字串排序
不会
成绩统计
判断+存不同组别的人数,分别计算
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int s[3];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
if(x>=85){
s[2]++;
}else if(x>=60){
s[1]++;
}else{
s[0]++;
}
}
int a=round(100.0*s[2]/n);
int b=round(100.0*(s[2]+s[1])/n);
printf("%d\%\n%d\%\n",b,a);
return 0;
}
子串分值和
ac 60%
理解起来比较简单,就是模拟了一下,分成不同长度的子串分别来计算
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int sum;
int main(){
string s;
cin>>s;
for(int k=1;k<=s.size();k++){
queue<int> q;
int cnt=0;
int n[26]={0};
for(int i=0;i<s.size();i++){
int t=s[i]-'a';
q.push(t);
if(q.size()>k){
int tt=q.front();
q.pop();
n[tt]--;
if(n[tt]==0) cnt--;
}
if(n[t]==0) cnt++;
n[t]++;
if(q.size()==k) sum+=cnt;
}
}
cout<<sum;
return 0;
ac 100%
这个解法不知道用了什么数学知识,反正我不会
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
int num[26];
int main(){
string s;
cin>>s;
int len=s.size();
memset(num,-1,sizeof(num));
LL res=0;
for (int i=0;i<len;++i){
res+=(LL)(i-num[s[i]-'a'])*(len-i);
num[s[i]-'a']=i;
}
printf("%lld\n",res);
return 0;
}
平面切分
平面上多一条直线+1,并且这条直线有一个交点额外+1
map存已经计算在内的点(判断每条直线之前要clear一下)
注意相同的直线和斜率不存在的直线
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef pair<double,double> PDD;
typedef pair<int,int> PII;
const int N=1e3+10;
PII v[N];
int n,res=1,cnt;
map<PDD,int> m;
bool flag;
int main(){
scanf("%d",&n);
int x,y;
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
v[i]={x,y};
cnt=1;
m.clear();
flag=false;
for(int j=1;j<i;j++){
if(i==1) break;
if(x==v[j].first && y==v[j].second){
flag=true;
break;
}
if(x==v[j].first) continue;
double xx=((double)y-v[j].second)/(v[j].first-x);
double yy=xx*x-y;
if(m[{xx,yy}]==0){
cnt++;
m[{xx,yy}]=1;
}
}
if(!flag) res+=cnt;
}
printf("%d",res);
return 0;
}