J题
-
题意
题目描述
财务计划要从家里出发,去N个城市出差,然后再回到家中,但N个出差地点之间不一定都能通车,现在他要筛选出花费最少的路径,你能帮帮他吗?
输入描述:
第一行为两个正整数N和M(1≤N≤300,1≤M≤N(N+1)/2),分别表示有N个出差地点和这些地点之间的M条通路,其中出差地点用1到N编号,而财务的家所在城市用编号0表示。
随后的M行,每行给出通路连接的两个城市和这条通路上的花费,格式为:
城市A 城市B 花费
通路是双向的,且两个城市间最多有一条通路,不存在自环。保证所有花费大于0。
再下一行给出一个正整数K(K<=20000),表示现在有K条推荐路径(注意:给出的路径不一定能通过或可能不满足财务的要求)。
接下来K行每一行表示一个推荐路径,第一个整数n表示途径的城市数,后面有n(n<=2*N)个整数xi(1≤xi≤N)(表示途经的城市(不包括财务的家),如:
3 1 2 3
表示实际路径为0→1→2→3→0。
输出描述:
请你检验给出的K条推荐路径,当它满足:
1.给出的路径能实际通车,即路径中相邻城市存在通路;
2.给出的路径恰好能都到达N个出差城市一次,即不能漏掉某个城市,也不能重复到达。
则称这条路径是可行的。
对于给出的K条推荐路径,请输出其中可行路径中最少的花费,若不存在可行路径,请输出"-1"。(题目保证花费和不超过int范围) -
思路
最好按照题意写就行,注意细节。
我写的一开始,一直wa的。
#include <bits/stdc++.h>
using namespace std;
const int N = 300;
int a[N][N];
int hsh[N];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int x, y, c;
cin >> x >> y >> c;
a[x][y] = a[y][x] = c;
}
int k;
cin >> k;
int res = 0x3f3f;
while (k--)
{
int n1;
cin >> n1;
vector<int> v;
set<int> s;
bool flag = true;
for (int i = 0; i < n1; i++)
{
int x;
cin >> x;
v.push_back(x);
}
for(int i=0;i<n1;i++)
{
int x=v[i];
if (s.find(x)!=s.end()&&x!=0)
{
flag = false;
break;
}
s.insert(x);
}
if (s.size() < n)
{
flag=false;
}
int ans = 0;
if (a[0][v[0]] != 0)
ans += a[0][v[0]];
else
{
flag = false;
}
if (a[0][v[n - 1]] != 0)
ans += a[0][v[n - 1]];
else
{
flag = false;
}
for (int i = 1; i < n; i++)
{
if (a[v[i]][v[i-1]])
{
ans += a[v[i]][v[i-1]];
}
else
{
flag = false;
break;
}
}
if(flag)
res = min(ans, res);
s.clear();
}
if (res == 0x3f3f)
cout << "-1" << endl;
else
cout << res << endl;
}
一个是题意没看清楚,而是有些地方不严谨。
看看人家的
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2005;
int g[maxn][maxn], a[maxn], vis[maxn];
int main() {
int n, m, k;
cin >> n >> m;
while(m--) {
int x, y, w;
cin >> x >> y >> w;
g[x][y] = g[y][x] = w;
}
cin >> k;
int pos = 0, mx = 0x3f3f3f3f, mxn = 0, cnt = 0;
while(pos++ < k) {
int sum = 0, f = 0;
cin >> m;
for(int i = 1; i <= m; ++i) cin >> a[i];
if(m == n) {
memset(vis, 0 ,sizeof vis);
if(g[0][a[1]] && g[a[m]][0]) f = 1, sum = g[0][a[1]] + g[a[m]][0];
vis[0] = vis[a[1]] = 0;
for(int i = 1; i < m; ++i) {
if(g[a[i]][a[i + 1]] && !vis[a[i + 1]]) {
vis[a[i + 1]] = 1;
sum += g[a[i]][a[i + 1]];
}
else {
f = 0;
break;
}
}
}
if(f) {
cnt++;
if(mx > sum) {
mx = sum;
mxn = pos;
}
}
}
if(!cnt) mx = -1;
cout << mx << endl;
return 0;
}
没有花里胡哨的。就直接模拟。
还有0x3f3f3f3f才比较到基本到int顶了。
自己写AC的
#include <bits/stdc++.h>
using namespace std;
const int N = 310;
int a[N][N];
int hsh[N];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int x, y, c;
cin >> x >> y >> c;
a[x][y] = a[y][x] = c;
}
int k;
cin >> k;
int res = 0x3f3f3f3f;
int f=0;
while (k--)
{
int n1;
cin >> n1;
int v[n1];
set<int> s;
bool flag = true;
int ans = 0;
for (int i = 0; i < n1; i++)
{
cin>>v[i];
}
if(n!=n1)
{flag=false;continue;}
if (a[0][v[0]])
ans += a[0][v[0]];
else
{
flag = false;
continue;
}
if (a[0][v[n1 - 1]])
ans += a[0][v[n1 - 1]];
else
{
flag = false;
continue;
}
for(int i=0;i<n1;i++)
{
int x=v[i];
if (s.find(x)!=s.end())
{
flag = false;
continue;
}
s.insert(x);
}
if (s.size() != n)
{
flag=false;
continue;
}
for (int i = 1; i <n1; i++)
{
if (a[v[i]][v[i-1]])
{
ans += a[v[i]][v[i-1]];
}
else
{
flag = false;
continue;
}
}
if(flag)
{res = min(ans, res);f=1;}
}
if (!f)
cout << "-1" << endl;
else
cout << res << endl;
}
AC之前最后一次wa竟然因为数组开小了。呜呜呜。真菜QQ。
L题,哎,本来有希望做出来的。
- 题意
- 思路
二分检验 - 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef long long ll;
ll a[N],w[N];
int n,k;
bool check(ll mid)
{
ll cnt=0;
for(int i=1;i<n;i++)
{
if(w[i]>mid)
{
cnt+=w[i]/mid;
if(w[i]%mid==0)
cnt--;
}
else
continue;
}
if(cnt<=k)
return false;
else
return true;
}
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+1+n);
for(int i=1;i<n;i++)
{
w[i]=a[i+1]-a[i];
}
ll l=0,r=1e12;
while(l<r)
{
ll mid=l+r>>1;
if(check(mid))
l=mid+1;
else
r=mid;
}
cout<<l<<endl;
}
B题
- 题意
- 思路
将前缀和模k,然后去找最长的相同的,因为一减就会%k==0,经典题。 - 代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
struct
{
int l=0;
int r=0;
}hsh[N];
void solve()
{
memset(hsh,0,sizeof(hsh));
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
a[1]%=k;
for(int i=2;i<=n;i++)
{
a[i]=(a[i]+a[i-1])%k;
}
for(int i=1;i<=n;i++)
{
if(hsh[a[i]].l==0)
hsh[a[i]].l=i;
else
hsh[a[i]].r=i;
}
int res=-1;
if(hsh[0].l==n||hsh[0].r==n)
cout<<n<<endl;
else
{
bool flag=false;
for(int i=0;i<=k;i++)
{
if(hsh[i].l==0&&hsh[i].r==0)
continue;
else if(hsh[i].l!=0&&hsh[i].r==0)
{
continue;
}
else
{
res=max(res,hsh[i].r-hsh[i].l);
flag=true;
}
}
if(hsh[0].l)
{
res=max(res,max(hsh[0].l,hsh[0].r));
flag=true;
}
if(flag)
cout<<res<<endl;
else
cout<<-1<<endl;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
solve();
}
}
大佬就是大佬,看看人家的代码
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int main() {
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin >> t;
while(t--) {
int n, k;
cin >> n >> k;
vector<int> a(n);
for(int i=0;i<n;++i) cin>>a[i];
int cur=0,ans=-1;
vector<int> lst(k, -1);
lst[0]=0;
for(int i=1;i<=n;++i) {
cur=(cur+a[i-1])%k;
if(lst[cur]!=-1) ans=max(ans,i-lst[cur]);
else lst[cur]=i;
}
cout<<ans<<'\n';
}
}