AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
const int N=110;
int a[N];
int n,h,x;
void solve() {
cin>>n>>h>>x;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
if(h+a[i]>=x){
cout<<i<<endl;
return;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--) {
solve();
}
return 0;
}
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
int n;
void solve() {
cin>>n;
set<int>s;
int maxn=0;
for(int i=1;i<=n;i++){
int x;
cin>>x;
maxn=max(maxn,x);
s.insert(x);
}
int y=*s.begin();
for(int i=y;i<=maxn;i++){
if(!s.count(i)){
cout<<i<<endl;
return;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--) {
solve();
}
return 0;
}
C - Remembering the Days (atcoder.jp)
一开始想的是最大生成树,但是了第三个样例后,知道这是不行的,因为不能有重复路径,树是可以走重复路径的
然后想到用dfs,对于每一个点进行dfs,然后对于找到的单向路径长度之和取max
错误代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=15;
int vis[N];
vector<PII>e[N];
int n,m;
int ans;
void dfs(int x,int d) {
vis[x]=1;
if(!e[x].size()) {
ans = max(ans, d);
return;
} else {
for(auto v:e[x]) {
int ver=v.first,dist=v.second;
if(!vis[ver]) {
dfs(ver,d+dist);
}
}
}
}
void solve() {
cin>>n>>m;
for(int i=1; i<=m; i++) {
int a,b,c;
cin>>a>>b>>c;
e[a].push_back({b,c});
e[b].push_back({a,c});
}
ans=0;
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) vis[j]=0;
dfs(i,0);
}
cout<<ans<<endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--) {
solve();
}
return 0;
}
错误之处在于:
第一个错误在于给答案赋值的时候,一直没有赋值进去,因为e[x],size()不可能等于0
其实完全可以一直赋值的,因为是取max,一直赋值的话是完全没有问题的
或者在遍历子节点时看有没有标记过的节点
第二个错误在于dfs没有恢复现场,当对图进行dfs时,一定要恢复现场
对图进行dfs的板子是固定的,如下:
void dfs(int x){
vis[x]=1;
for(auto v:e[x]){
if(!vis[v]) dfs(v);
}
vis[x]=0;
}
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N=15;
int vis[N];
vector<PII>e[N];
int n,m;
int ans;
void dfs(int x,int d) {
vis[x]=1;
ans=max(ans,d);
for(auto v:e[x]) {
int ver=v.first,dist=v.second;
if(!vis[ver]) {
dfs(ver,d+dist);
}
}
vis[x]=0;
}
void solve() {
cin>>n>>m;
for(int i=1; i<=m; i++) {
int a,b,c;
cin>>a>>b>>c;
e[a].push_back({b,c});
e[b].push_back({a,c});
}
ans=0;
for(int i=1; i<=n; i++) {
for(int j=1;j<=n;j++) vis[j]=0;
dfs(i,0);
}
cout<<ans<<endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--) {
solve();
}
return 0;
}
一开始想贪心,每次贪席位最多的,但是后面想了想是不可能的,因为可能席位最多的那个,需要转移很多很多很多很多的票
如果一开始有贪心的思路,那么先不要急着写代码,先思考该贪心思路是否真的可行
错误代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#define endl '\n'
#define int long long
using namespace std;
typedef long long ll;
const int N=110;
int n;
struct node{
int x,y,z;
int diff;
bool operator<(const node &W)const{
if(z==W.z) return diff<W.diff;
return z>W.z;
}
}q[N];
void solve() {
cin>>n;
int sum=0;
for(int i=1;i<=n;i++) {
cin>>q[i].x>>q[i].y>>q[i].z;
if(q[i].y>q[i].x) q[i].diff=q[i].y-q[i].x;
else q[i].diff=0;
sum+=q[i].z;
}
sort(q+1,q+1+n);
int res=0;
int ans=0;
// for(int i=1;i<=n;i++){
// cout<<q[i].x<<' '<<q[i].y<<' '<<q[i].z<<endl;
// }
for(int i=1;i<=n;i++){
res+=q[i].z;
if(q[i].diff) ans+=q[i].diff/2+1;
if(sum-res<res) break;
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--) {
solve();
}
return 0;
}
这题其实是01背包的变式,与经典的01背包问题不同,f[i][j]表示在前i个物品里选,价值为j所需要的物品最小重量
该题f[i][j]表示在前i场投票中选择若干场投票进行票数转移,赢得j个席位所需要转移的最少票数
枚举席位数,从0到sum
for(int i=1;i<=n;i++){
for(int j=0;j<=sum;j++){
//不获得第i场的席位
f[i][j]=f[i-1][j];
//获得第i场的席位
if(a[i]>b[i]&&j-c[i]>=0) f[i][j]=min(f[i][j],f[i-1][j-c[i]]+0);//如果a[i]本来就大于b[i],那么不需要转移票数,直接获得席位,从j-c[i]转移到j,加0表示不需要转移票
else if(a[i]<=b[i]&&j-c[i]>=0) f[i][j]=min(f[i][j],f[i-1][j-c[i]]+(b[i]-a[i])/2+1);//由于该场获得了c[i],所以从j-c[i]转移到j,最少需要转移的票数为(b[i]-a[i])/2+1
}
}
这样的话,需要f[100][1e7],这样就爆空间了,所以优化为一维
for(int i=1;i<=n;i++){
for(int j=sum;j>=c[i];j--){
if(a[i]>b[i]) f[j]=min(f[j],f[j-c[i]]+0);//如果a[i]本来就大于b[i],那么不需要转移票数,直接获得席位,从j-c[i]转移到j,加0表示不需要转移票
else if(a[i]<=b[i]) f[j]=min(f[j],f[j-c[i]]+(b[i]-a[i])/2+1);//由于该场获得了c[i],所以从j-c[i]转移到j,最少需要转移的票数为(b[i]-a[i])/2+1
}
}
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define endl '\n'
#define int long long
using namespace std;
typedef long long ll;
const int N=110,M=1e7+10;
int a[N],b[N],c[N];
int f[M];
int n;
void solve() {
cin>>n;
int sum=0;
for(int i=1; i<=n; i++) {
cin>>a[i]>>b[i]>>c[i];
sum+=c[i];
}
memset(f,0x3f,sizeof f);
f[0]=0;
for(int i=1; i<=n; i++) {
for(int j=sum; j>=c[i]; j--) {
if(a[i]>b[i]) f[j]=min(f[j],f[j-c[i]]+0);//如果a[i]本来就大于b[i],那么不需要转移票数,直接获得席位,从j-c[i]转移到j,加0表示不需要转移票
else if(a[i]<=b[i]) f[j]=min(f[j],f[j-c[i]]+(b[i]-a[i])/2+1);//由于该场获得了c[i],所以从j-c[i]转移到j,最少需要转移的票数为(b[i]-a[i])/2+1
}
}
int ans=1e18;
//枚举席位数大于半数时最少需要转移的票数
for(int i=(sum+1)/2;i<=sum;i++){
ans=min(ans,f[i]);//一直取min就行了,某些席位i可能组成不了(因为席位都是一个个离散的数,不是连续的),则f[i]为无穷大
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--) {
solve();
}
return 0;
}
E - Avoid Eye Contact (atcoder.jp)
最短路,用bfs
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define endl '\n'
//#define int long long
using namespace std;
typedef long long ll;
const int N=2010;
char s[N][N];
int vis[N][N];//标记是否可走以及是否走过
int h,w;
int x,y;
int dx[4]= {-1,1,0,0},dy[4]= {0,0,-1,1};
struct node {
int x,y;
int d;
};
queue<node>q;
int bfs() {
q.push({x,y,0});
s[x][y]='#';
while(q.size()) {
auto t=q.front();
q.pop();
int x=t.x,y=t.y,d=t.d;
for(int i=0; i<4; i++) {
int tx=x+dx[i],ty=y+dy[i];
if(tx<1||tx>h||ty<1||ty>w) continue;
if(vis[tx][ty]==1||s[tx][ty]=='#') continue;
if(s[tx][ty]=='G') return d+1;
if(s[tx][ty]='.') {
q.push({tx,ty,d+1});
s[tx][ty]='#';
}
}
}
return -1;
}
void solve() {
cin>>h>>w;
for(int i=1; i<=h; i++) {
for(int j=1; j<=w; j++) {
cin>>s[i][j];
if(s[i][j]=='S') {
x=i;
y=j;
}
}
}
//预处理障碍
for(int i=1; i<=h; i++) {
for(int j=1; j<=w; j++) {
if(s[i][j]=='^') {
vis[i][j]=1;
int k=i-1;
while(k>=1&&(s[k][j]=='.'||s[k][j]=='S'||s[k][j]=='G')) {
vis[k][j]=1;
k--;
}
} else if(s[i][j]=='v') {
vis[i][j]=1;
int k=i+1;
while(k<=h&&(s[k][j]=='.'||s[k][j]=='S'||s[k][j]=='G')) {
vis[k][j]=1;
k++;
}
} else if(s[i][j]=='<') {
vis[i][j]=1;
int k=j-1;
while(k>=1&&(s[i][k]=='.'||s[i][k]=='S'||s[i][k]=='G')) {
vis[i][k]=1;
k--;
}
} else if(s[i][j]=='>') {
vis[i][j]=1;
int k=j+1;
while(k<=w&&(s[i][k]=='.'||s[i][k]=='S'||s[i][k]=='G')) {
vis[i][k]=1;
k++;
}
}
}
}
// cout<<endl;
// for(int i=1;i<=h;i++){
// for(int j=1;j<=w;j++){
// cout<<vis[i][j];
// }
// cout<<endl;
// }
cout<<bfs()<<endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--) {
solve();
}
return 0;
}