- 伍衍 的博客
DAY2
- @ 2024-7-9 19:52:20
考试错误:
已经有了这道题的思路,但是在考虑的时候,忽略了的情况。所以只拿了分,不过还好及时发现了,没有失分。
思路:
.如果,直接输出-, ;
.如果,输出。
.否则遍历数组,找到一个"分水岭",使得它左右两边 都能消。找到输出,没找到输出。 代码:
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+50;
int a[N];
int main(){
freopen("num.in", "r", stdin);
freopen("num.out", "w", stdout);
int n;
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
}
if(a[1]==a[n]&&n!=1){
cout << 1;
return 0;
}
for(int i=2;i<n-1;i++){
if(a[i]==a[1]&&a[i+1]==a[n]){
cout << 2;
return 0;
}
}
cout << -1;
return 0;
}
考试错误:不会做,骗分的,没发生错误。
不会做原因:在考试时只想到了有极大值的情况,没考虑气球数量的奇偶性带来的影响。
思路:
.如果有一个气球的数量其他的气球总数量,那么输出, ;
.如果气球总数为奇数,那么任意一个气球都有可能剩下个,输出, ;
.如果总数为偶数。那么只要气球数 就可以留下,输出数量 的气球种类数。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+50;
int mx,ans,cnt;
int a[N];
signed main(){
freopen("balloon.in", "r", stdin);
freopen("balloon.out", "w", stdout);
int n;
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
mx=max(mx,a[i]);
ans+=a[i];
if(a[i]==1) cnt++;
}
if(n==2&&a[1]==a[2]) cout << 0;
else if(mx>=ans-mx) cout << 1;
else if(ans%2) cout << n;
else if(ans%2==0) cout << n-cnt;
}
考试错误:无,一遍的。
思路:
.大模拟题,小的加,大的减,没什么好说的,只是代码长一点而已(行不长吧…)。
.注意特判(数据不严谨,没有出,想挑战的话试试这组数据: 或 ):如果 两个数都为,则根据下一次用到的数来决定加哪个(用到那个加哪个,都用到了随便加)。
代码:
#include <bits/stdc++.h>
using namespace std;
string t;
string s;
vector<string> vctr;
int n,a,b,c;
int main(){
freopen("game.in", "r", stdin);
freopen("game.out", "w", stdout);
cin >> n >> a >> b >> c;
for(int i=1;i<=n;i++){
cin >> s;
vctr.push_back(s);
}
for(int i=0;i<vctr.size();i++){
if(vctr[i]=="AB"){
if(a==1&&b==1){
if(i==vctr.size()-1){
t=t+"A";
}else{
if(vctr[i+1]=="BC"){
a--,b++;
t=t+"B";
}else{
a++,b--;
t=t+"A";
}
}
}else{
if(!a&&!b){
cout << "No";
return 0;
}
if(a>b){
a--,b++;
t=t+"B";
}else{
a++,b--;
t=t+"A";
}
}
}if(vctr[i]=="BC"){
if(b==1&&c==1){
if(i==vctr.size()-1){
t=t+"B";
}else{
if(vctr[i+1]=="AC"){
b--,c++;
t=t+"C";
}else{
b++,c--;
t=t+"B";
}
}
}else{
if(!c&&!b){
cout << "No";
return 0;
}
if(b>c){
b--,c++;
t=t+"C";
}else{
b++,c--;
t=t+"B";
}
}
}if(vctr[i]=="AC"){
if(a==1&&c==1){
if(i==vctr.size()-1){
t=t+"A";
}else{
if(vctr[i+1]=="AB"){
a++,c--;
t=t+"A";
}else{
a--,c++;
t=t+"C";
}
}
}else{
if(!a&&!c){
cout << "No";
return 0;
}
if(a>c){
a--,c++;
t=t+"C";
}else{
a++,c--;
t=t+"A";
}
}
}
}
cout << "Yes\n";
for(int i=0;i<t.size();i++){
cout << t[i] << endl;
}
}
不会做原因:对图的理解不深刻,导致不会用标记数组的方法来做。
思路:
.初始化:时候将标记数组全设为。
.每次连接时判断高度,高度低的就设为,一样就都设为。
.最后输出所有是的台子(仙峰台)的个数。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+20;
int a[N],st[N];
signed main(){
freopen("penglai.in", "r", stdin);
freopen("penglai.out", "w", stdout);
int n,m;
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> a[i];
st[i]=1;
}for(int i=1;i<=m;i++){
int x,y;
cin >> x >> y;
if(a[x]<=a[y]){
st[x]=0;
}if(a[y]<=a[x]){
st[y]=0;
}
}
int cnt=0;
for(int i=1;i<=n;i++){
if(st[i]) cnt++;
}
cout << cnt;
}
考试错误:不会优化,骗分的,没发生错误。
不会做原因:在做题时没有打草稿,没有推公式,所以只能暴力骗分。
思路:
.设+是(,)的倍数。
.不难发现(,)是的倍数,而+是(,)的倍数,所以+是的倍数,也就是的倍数。
.是的倍数,所以(,)。将(,)等量代换成,所以题目变成+是的倍数(这里用连除,防止溢出)。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,ans;
signed main(){
freopen("math1.in", "r", stdin);
freopen("math1.out", "w", stdout);
cin >> n >> m;
for(int b=1;b<=m;b++)
for(int a=b;a<=n;a+=b)
if((a+b)%(b*b)==0) ans++;
cout << ans;
}
不会做原因:对的理解不深,以后还要多去积累。
DP思路:
状态表示:f[i][j]:第天到达第个小屋的方案数
注意:r[i]=l[i]+s[i],且i,j,k是三重循环遍历。
状态计算:sum+=r[j]*r[k]-l[j]*l[k]*f[i-1][k]。
代码:
#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
long long n,m,s[110],l[110],r[110],dp[1010][110];
bool f[100010];
int main(){
freopen("walk.in","r",stdin);
freopen("walk.out","w",stdout);
cin >> m >> n;
for(long long i=1;i<=m;i++) cin >>s[i];
for(long long i=1;i<=m;i++){
cin >> l[i];
r[i]=l[i]+s[i];
}
dp[0][1]=1;
for(long long i=1;i<=n;i++){
for(long long j=1;j<=m;j++){
long long sum=0;
for(int k=1;k<=m;k++){
sum+=(r[j]*r[k]-l[j]*l[k])*dp[i-1][k];
sum%=mod;
}
dp[i][j]=sum;
}
}
long long sum=0;
for(long long i=1;i<=m;i++){
sum+=dp[n][i];
sum%=mod;
}
cout << sum;
return 0;
}