文章目录
Week 1 星期五 性感素数(选择结构+素数判断)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
bool judge(int n)
{
if(n<2) return 0;
for(int i=2;i*i<=n;i++)
if(n%i==0)
return 0;
return 1;
}//素数判断
int main()
{
cin>>n;
if(judge(n)&&judge(n-6))
{
puts("Yes");
cout<<n-6;
return 0;
}//先找小的匹配性感素数
if(judge(n)&&judge(n+6))
{
puts("Yes");
cout<<n+6;
return 0;
}//找不到小的找大的匹配性感素数
for(int i=n+1;;i++)
{
if(judge(i)&&judge(i+6)||judge(i)&&judge(i-6))
{
cout<<"No"<<endl<<i;
break;
}
}//都找不到往后搜索找一个性感素数
}
Week 4 星期四 哈夫曼树
思路
小根堆模拟即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
priority_queue<int,vector<int>,greater<int>>qu;//小根堆
int n,k,sum;
int main()
{
cin>>n;
while(n--)
{
cin>>k;
qu.push(k);
}
while(qu.size()!=1)
{
int a=qu.top();
qu.pop();
int b=qu.top();
qu.pop();
sum+=a+b;
qu.push(a+b);
}
cout<<sum;
}
Week 4 星期五 数值转换
思路
先转换成十进制,然后转换成任意进制
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a,c,k;
string b;
char c1[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char cc[10001];
int cnt;
void solve()
{
int len=b.size();
for(int i=0;i<len;i++)
{
if(b[i]>='0'&&b[i]<='9') k+=(b[i]-'0')*pow(a,len-i-1);
if(b[i]>='a'&&b[i]<='z') k+=(b[i]-'a'+10)*pow(a,len-i-1);
if(b[i]>='A'&&b[i]<='Z') k+=(b[i]-'A'+10)*pow(a,len-i-1);
}
while(k)
{
cc[++cnt]=c1[k%c];
k/=c;
}
}
int main()
{
cin>>a>>b>>c;
solve();
for(int i=cnt;i>=1;i--) cout<<cc[i];
return 0;
}
Week 4 星期日 倒水问题(暴力搜索)
原题链接:
倒水问题
思路:
一开始读理所当然的想到了贝祖定理和扩展欧几里得,但是仔细读题后发现并不是那回事,仔细看了题解后回来补题。
是一个搜索题,暴力搜索所有的状态即可;
A,B,C 的范围都是 0 ~ 4000 看起来状态数好像有 40013 那么多(必爆),但其实不然,因为每次转移必须保证 一个杯子是空的或者一个杯子是满的,这样最坏复杂度就降低到 3 ∗ 2 ∗ 4000 ∗ 4000 3*2*4000*4000 3∗2∗4000∗4000 大约是 9.6*107 也就是 1e8
一开始三杯水的状态为 (0,0,C)
开始倒水即状态开始转移后,转移方向是
a - b
a - c
b - a
b - c
c - a
c - b
这六个方向,我们根据题意进行转移即可
注意不计算重复的状态,每次的状态为(a,b,c),a,b,c 满足 a+b==c 因此我们只要记下其中两个数的状态就相当于表示出了这三个数的状态,我们用 set 来存状态,状态不同的时候 C 有可能相同, 我们用另一个 set 来存 所有不同的的C,统计C的答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+7;
int A,B,C;
typedef pair<int,int> PII;
set<PII>st;
set<int>ans;
/*
a - b
a - c
b - a
b - c
c - a
c - b
*/
void dfs(int a,int b,int c)
{
if(st.count({a,b})) return ;
st.insert({a,b});//记录状态
ans.insert(c);//记录当前状态下的答案
int x;
x=min(a,B-b);
dfs(a-x,b+x,c);//a - b
x=min(a,C-c);
dfs(a-x,b,c+x);//a - c
x=min(b,A-a);
dfs(a+x,b-x,c);//b - a
x=min(b,C-c);
dfs(a,b-x,c+x);//b - c
x=min(c,A-a);
dfs(a+x,b,c-x);//c - a
x=min(c,B-b);
dfs(a,b+x,c-x);//c - b
}
int main()
{
while(cin>>A>>B>>C)
{
ans.clear();
st.clear();
dfs(0,0,C);
cout<<ans.size()<<endl;
}
}
总结
以后看题要好好读题,不能看着像就用某种思路,这题的各种小细节都特别巧妙,包括它搜索的方法(状态的转移),记录的方法,应当好好学习这个题。
Week 5 星期一 树查找(选择结构)
思路:
第k层的左侧序号 l 是 2k-1 右侧序号 r 是 2k-1
判断是否为空 即判断 n 与 l 的 大小关系
而当不为空的时候,也要注意这一层是否完全
注意格式
左移 k 即为 × 2k
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e4+10;
int n,k;
int a[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
cin>>k;
int r=(1<<k)-1;
int l=1<<(k-1);
if(n<l)
{
cout<<"EMPTY";
}
else
{
r=min(r,n);
for(int i=l;i<=r;i++)
{
if(i!=r) cout<<a[i]<<" ";
else cout<<a[i];
}
}
}
Week 5 星期二 日期类(选择结构+闰年判断)
注意:
闰年的判断条件是 是4的倍数不是100的倍数或者是400的倍数
#include<bits/stdc++.h>
using namespace std;
int n,m,maxn;
int a,b,c;
int t;
bool judge(int a)
{
if(a%4==0&&a%100!=0||a%400==0) return 1;
return 0;
}
int main()
{
cin>>t;
while(t--)
{
cin>>a>>b>>c;
c++;
if(b==1||b==3||b==5||b==7||b==8||b==10||b==12)
{
if(c==32)
{
c=1;
b++;
}
}
if(b==4||b==6||b==9||b==11)
{
if(c==31)
{
c=1;
b++;
}
}
if(b==2)
{
if(judge(a))
{
if(c==30)
{
c=1;
b++;
}
}
else
{
if(c==29)
{
c=1;
b++;
}
}
}
if(b==12)
{
b=1;
a++;
}
printf("%d-%02d-%02d\n",a,b,c);
}
}