How Can I Solve My Dynamic Programming Problem? - c++

Here is my code:
#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define M 1000000007
#define INF 1000000007
typedef pair<lli,lli> ll;
#define mem(a,x) memset(a,x,sizeof(a))
lli n,k,m;
lli dist[507][507];
lli path1[207][207];
vector<int> v2(1005,1);
vector<double> v;
lli x,y,c,z,t,q,u,d,a1,b;
struct edge
{
lli a,b,cost;
};
/*void djkstra(int x,vector<ll> v[])
{
mem(vis,0);
dist[x]=0;
s2.insert({0,x});
while(!s2.empty())
{
ll p=*s2.begin();
s2.erase(s2.begin());
x=p.second;
if(vis[x])
continue;
vis[x]=1;
for(int j=0;j<v[x].size();j++)
{
if(dist[v[x][j].second]>dist[x]+v[x][j].first)
{
dist[v[x][j].second]=dist[x]+v[x][j].first;
s2.insert({dist[v[x][j].second],v[x][j].second});
a[v[x][j].second]=x;
}
}
}
}*/
lli parent[100007];
lli find(lli a)
{
return a==parent[a]?a:parent[a]=find(parent[a]);
}
void dset(lli n)
{
for(int j=0;j<=n;j++)
parent[j]=j;
}
void unio(lli a,lli b,lli rank[])
{
if(rank[find(a)]>rank[find(b)])
parent[find(b)]=find(a);
else if(rank[find(b)]>rank[find(a)])
parent[find(a)]=find(b);
else
{
parent[find(a)]=find(b);
rank[find(b)]++;
}
}
bool check(lli a)
{
if((a1*a*m+b*(a-1)+d)>=x)
return true;
return false;
}
/*bool valid(int i,int x)
{
for(int j=1;j<x;j++)
{
if((abs(b[j-1]-i)==abs(j-x))||(i==b[j-1])||(j==x))
return false;
}
return true;
}*/
lli p[10007];
lli dp[301][301][301];
map<ll,ll> pat;
map<ll,lli> p2;
lli pr[200007],we[200007];
lli a[100005];
map<lli,lli> m4;
vector<int> v4;
int f=0;
lli tot=1;
lli vis[1001][1001];
lli p1;
lli s[10001];
lli n1;
lli solve(lli n,lli i,lli c)
{
//cout<<n<<" "<<i<<" "<<a[i]<<" "<<dp[n][i]<<endl;
if(i>n1)
return 0;
if(c==0&&n>0)
return 0;
if(c==0&&n==0)
return 1;
if(n<0)
return 0;
if(dp[n][i][c]!=-1)
return dp[n][i][c];
dp[n][i][c]=solve(n-i,i,c-1);
dp[n][i][c]+=solve(n,i+1,c);
return dp[n][i][c];
}
int main()
{
while(1)
{
string s="\0";
getline(cin,s);
if(s.size()==0)
return 0;
string d[3];
d[0]="\0";
d[1]="\0";
d[2]="\0";
int c=0;
for(int i=0;i<=300;i++)
{
for(int j=1;j<=300;j++)
{
for(int k=1;k<=300;k++)
dp[i][j][k]=-1;
}
}
for(int j=0;j<s.length();j++)
{
if(s[j]!=' ')
d[c]+=s[j];
else
c++;
}
int f;
stringstream ss(d[0]);
ss>>f;
n1=f;
lli d1=0;
for(int i=1;i<=f;i++)
d1+=solve(f,1,i);
for(int i=0;i<=300;i++)
{
for(int j=0;j<=300;j++)
dp[0][i][j]=1;
}
lli sum[f+1];
mem(sum,0);
sum[0]=1;
for(int i=1;i<=f;i++)
{
if(i==1)
sum[i]=dp[f][1][i];
else
sum[i]=sum[i-1]+dp[f][1][i];
}
if(c==0)
{
if(f!=0)
cout<<d1<<endl;
else
cout<<1<<endl;
}
else if(c==1)
{
int f1;
stringstream ss1(d[1]);
ss1>>f1;
if(f1>f)
f1=f;
cout<<sum[f1]<<endl;
}
else
{
int f1,f2;
stringstream ss1(d[1]);
ss1>>f1;
stringstream ss2(d[2]);
ss2>>f2;
if(f1>f)
cout<<0<<endl;
else
{
if(f2>f)
f2=f;
cout<<sum[f2]-sum[f1]+dp[f][1][f1]<<endl;
}
}
}
}
In the following function:
lli solve(lli n,lli i,lli c)
My solution is O(N^3), and it should pass the test cases (N=300), but still time limit exceeds for it.
How can I solve this problem?
Here is the problem link.

Ok so the point the dynamic programming is being able to reuse what was already done.
So how to reuse your code?
Here's my idea:
let say the total amount is 6$ and we know we have a total of 3 pieces maximum totalize that amount. You can begin to try by beginning with by finding the way to make a total of 1$, than 2$, 3$, .. alway reusing what you done before.
Example
1 $ total
only way 1x1$ (keep that in memory)
2 $ total
-decompose in all possible 2 pieces you can add: 1+1, 2
-to find other possibilities, reuse what you done before recursivly (the recursion at this level stops after only the first iteration because 1$ is the minimum dollar value)
-keep that in memory
... (continue like that with 3 $ total, 4 $ total, 5$ total ...)
6$ total
-decompose in all possible 2 pieces you can add: 6, 1+5, 2+4 3+3 (always (n intDiv 2) +1 possibilities) possibilites
-to find other possibilities, reuse what you done before recursivly:
example: for the 3+3 possibility, go look at all the possibilities found at 3$ total to find all possibilities.
- Remove all possibilites that used too much pieces.
You finished by finding all possibilities as an answer: 1+1+4, 1+2+3, 3+3 and 2+2+2.
Hope it helps :)

Related

Getting wrong answer in a DP problem although implementation looks correct

I was trying to solve Reduce String on codechef which says
Give a string s of length l, and a set S of n sample string(s). We do reduce the string s using the set S by this way:
Wherever Si appears as a consecutive substring of the string s, you can delete (or not) it.
After each deletion, you will get a new string s by joining the part to the left and to the right of the deleted substring.
I wrote a recursive function as follows:-
Basically what i am doing in my code is either don't delete the character or delete it if it is part of any substring but it is giving wrong answer.
#include <bits/stdc++.h>
using namespace std;
#define mx 255
int dp[mx];
unordered_map<string,int> sol;
void init(int n)
{
for(int i=0;i<n;i++)
{
dp[i]=-1;
}
}
int solve(string str,int low,int high,vector<string> smp)
{
if(low>high)
{
return 0;
}
if(dp[low]!=-1)
{
return dp[low];
}
int ans=1+solve(str,low+1,high,smp);
for(int i=low;i<high;i++)
{
string tem=str.substr(low,i-low+1);
for(int j=0;j<smp.size();j++)
{
cout<<"low i high str"<<low<<" "<<i<<" "<<high<<" "<<smp[j]<<" "<<tem<<endl;
if(tem.compare(smp[j])==0)
{
ans=min(ans,solve(str,i+1,high,smp));
}
}
}
return dp[low]=ans;
}
signed main()
{
sol.clear();
string str;
vector<string> smp;
int n;
cin>>str;
cin>>n;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
smp.push_back(tem);
}
int len=str.length();
init(len+1);
cout<<solve(str,0,len-1,smp)<<endl;
return 0;
}
PS:
link to the question
This question is toughest(seen so far) and most beautiful(again seen so far) question based on DP ON INTERVALS.
The initial code would definitely not work since it only considers single pass on the string and would not consider remaining string after deleting the patterns again and again.
There are 3 cases:-
Case 1 Either character is not deleted.
Case 2It is deleted as a part of contiguous substring.
Case 3It is deleted as a part of subsequence that matches any word given in the set of patterns and everything that is not part of that subsequence is deleted first as a substring(which again belongs to set of words).
The third part is the most tricky and requires enough thinking and is even tougher to implement too.
So for every substring we need to check whether this substring can be completely destroyed or not.
The function compute_full_recur() is the function that ensures that whether substring can be deleted either in Case 2 or Case 3.
The function compute_full takes care of Case 1.And finally this code will not run on codechef link since all the function are recursive with memoization but to verify the code is working i Have run it on Problem Reducto of Hackerrank which is exact similar with lower constraints.Download test cases and then run on test cases on your PC for verifying.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define mx 252
#define nx 40
bool full[mx][mx],vis[mx][mx],full_recur[mx][mx][nx][nx];
int ans[mx];
void init()
{
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
full[i][j]=false,vis[i][j]=false;
}
}
for(int i=0;i<mx;i++)
{
ans[i]=-1;
}
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
for(int k=0;k<nx;k++)
{
for(int l=0;l<nx;l++)
{
full_recur[i][j][k][l]=false;
}
}
}
}
}
bool compute_full_recur(string str,int low,int high,vector<string> pat,int idx,int len)
{
if(low>high&&len==pat[idx].length())
{
return true;
}
if(low>high&&len<pat[idx].length())
{
full_recur[low][high][idx][len]=false;
return false;
}
if(str[low]==pat[idx][len]&&compute_full_recur(str,low+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
for(int i=low+1;i<=high;i++)
{
if(str[low]==pat[idx][len]&&full[low+1][i]&&compute_full_recur(str,i+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
}
full_recur[low][high][idx][len]=false;
return false;
}
void compute_full(string str,int low,int high,vector<string> pats)
{
if(low>high)
{
return;
}
if(vis[low][high])
{
return;
}
vis[low][high]=true;
compute_full(str,low+1,high,pats);
compute_full(str,low,high-1,pats);
for(int i=0;i<pats.size();i++)
{
if(!full[low][high])
full[low][high]=compute_full_recur(str,low,high,pats,i,0);
}
}
int compute_ans(string str,int low,int high)
{
if(low>high)
{
return 0;
}
if(ans[low]!=-1)
{
return ans[low];
}
int sol=1+compute_ans(str,low+1,high);
for(int i=low+1;i<=high;i++)
{
if(full[low][i]==true)
{
sol=min(sol,compute_ans(str,i+1,high));
}
}
return ans[low]=sol;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
string str;
int n;
vector<string> pats;
cin>>n>>str;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
pats.push_back(tem);
}
init();
compute_full(str,0,str.length()-1,pats);
cout<<compute_ans(str,0,str.length()-1)<<endl;
}
return 0;
}

Find segmentation fault while passing map to function C++

I can't find the segmentation fault which is occuring on the line where I am calling calculate_grundy in main. Please help.
I have also added a screenshot of my debugger while debugging the code.
This is a question of a running contest so please don't answer logic problems instead of helping me in finding the segmentation fault.
I am passing the dp map for storing the subproblems, as done in dynamic programming.
#include<bits/stdc++.h>
#define ll long long int
using namespace std;
ll calculate_mex(unordered_set<ll> Set)
{
ll mex = 0;
while(Set.find(mex)!=Set.end())
{
mex++;
}
return mex;
}
ll calculate_grundy(ll n,ll m,map<pair<ll,ll>,ll> &dp)
{
auto it = dp.find(make_pair(n,m));
if(it!=dp.end())
{
return it->second;
}
else
{
ll ans;
ll greater = max(n,m);
ll smaller = min(n,m);
if(n==m || m==0 || n==0)
{
return 0;
}
else if(n==1 || m==1)
{
return n==1?m:n;
}
unordered_set<ll> Set;
ll limit = greater%smaller;
for(ll i=1;i<=limit;i++)
{
ll mult = smaller*i;
Set.insert(calculate_grundy(greater-mult,smaller,dp));
}
ans = calculate_mex(Set);
dp.insert(make_pair(make_pair(n,m),ans));
return ans;
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
ll t;
cin>>t;
while(t--)
{
ll n,m;
cin>>n>>m;
map<pair<ll,ll>,ll> dp;
if(calculate_grundy(n,m,dp)==0)
{
cout<<"Ari"<<"\n";
}
else
{
cout<<"Rich"<<"\n";
}
}
}

Why stack flow before execute main()

I wrote code to implement graph's ADT with adjacent matrix. Then I want to build a project and desperate code.
#include<iostream>
#include<iomanip>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e3+10;
class Graph{
private:
int vertex;
int side;
int is_vis[maxn];
int degree[maxn];
int Edges[maxn][maxn];
public:
Graph(){
vertex=0;
memset(Edges,0x3f,sizeof Edges);
memset(is_vis,0,sizeof is_vis);
memset(degree,0,sizeof degree);
}
void Clear(){
vertex=0;
memset(Edges,0x3f,sizeof Edges);
memset(is_vis,0,sizeof is_vis);
memset(degree,0,sizeof degree);
}
void Clear_Vis(){memset(is_vis,0,sizeof is_vis);}
void PreVisit(int v){cout<<v<<" ";}
void SetMark(int u,int vis){is_vis[u]=vis;}
void Set_vertex(int n){vertex=n;} //顶点数
int Get_vertex(){return vertex;}
int Get_side() {return side;} //边数
void Add_edge(int u,int v,int val){ //加边
if(Edges[u][v]==INF){
side++;
degree[u]++;degree[v]++;
}
Edges[u][v]=Edges[v][u]=val;
}
void Cancle_edge(int u,int v){ //删边
if(Edges[u][v]!=INF){
side--;
degree[u]--;degree[v]--;
}
Edges[u][v]=Edges[v][u]=INF;
}
bool Have_edge(int u,int v){ //判断边是否存在
return Edges[u][v]==INF?0:1;
}
int Get_degree(int u){ //返回顶点u的度数
return degree[u];
}
void The_edge_node(int u){ //与顶点u相邻的点
int flag=1;
for(int i=0;i<vertex;i++){
if(i!=u&&Edges[u][i]!=INF){
cout<<i<<" ";flag=0;
}
}
if(flag)cout<<"No node next to "<<u<<".";
cout<<endl;
}
void DFS(int u){ //深度优先遍历
if(is_vis[u])return;
PreVisit(u);
SetMark(u,1);
for(int i=0;i<vertex;i++){
if(i==u||Edges[u][i]==INF||is_vis[i])continue;
DFS(i);
}
}
void BFS(int u){ //宽度优先遍历
memset(is_vis,0,sizeof is_vis);
queue<int>Q;
Q.push(u);
is_vis[u]=1;
while(!Q.empty()){
int out=Q.front();Q.pop();
cout<<out<<" ";
for(int i=0;i<vertex;i++){
if(i==out||Edges[out][i]==INF||is_vis[i])continue;
is_vis[i]=1;
Q.push(i);
}
}
}
void prt_Gra(){ //打印邻接矩阵
cout<<" ";
for(int i=0;i<vertex;i++){
cout<<" "<<left<<setw(3)<<i;
}
cout<<endl;
for(int i=0;i<vertex;i++){
cout<<" ";
for(int j=0;j<vertex*4;j++)cout<<"-";cout<<"-"<<endl;
cout<<left<<setw(2)<<i;
for(int j=0;j<vertex;j++){
cout<<"|";
if(i==j)cout<<left<<setw(3)<<0;
else if(Edges[i][j]==INF)cout<<left<<setw(3)<<'-';
else cout<<left<<setw(3)<<Edges[i][j];
}
cout<<"|"<<endl;
}
cout<<" ";
for(int j=0;j<vertex*4;j++)cout<<"-";cout<<"-"<<endl;
}
}My_graph;
void Get_menus(){
cout<<"1.新建一个图。"<<endl;
cout<<"2.增加一条边。"<<endl;
cout<<"3.删除一条边。"<<endl;
cout<<"4.判断边是否存在。"<<endl;
cout<<"5.查询顶点的度数。"<<endl;
cout<<"6.输出图的邻接矩阵。"<<endl;
cout<<"7.查询与顶点相邻的点。"<<endl;
cout<<"8.对图进行深度优先遍历。"<<endl;
cout<<"9.对图进行宽度优先遍历。"<<endl;
}
int main(){
My_graph.Clear();
int cmd,n,m,u,from,to,dist;
Get_menus();
while(1){
cout<<"请输入对应操作的序号:";cin>>cmd;cout<<endl;
if(cmd==1){
My_graph.Clear();
cout<<"请输入图的顶点数:";cin>>n;
My_graph.Set_vertex(n);cout<<endl;
cout<<"请输入图的边数:";cin>>m;cout<<endl;
cout<<"请依次输入各边的端点与长度:"<<endl;
for(int i=0;i<m;i++){
cin>>from>>to>>dist;
My_graph.Add_edge(from,to,dist);
}
cout<<"图的初始化完成!"<<endl;
}
if(cmd==2){
cout<<"请输入新增边的端点与长度:"<<endl;
cin>>from>>to>>dist;
My_graph.Add_edge(from,to,dist);
cout<<"加边完成!"<<endl;
}
if(cmd==3){
cout<<"请输入边的两个端点:";
cin>>from>>to;
My_graph.Cancle_edge(from,to);
cout<<"删边完成!"<<endl;
}
if(cmd==4){
cout<<"请输入边的两个端点:";
cin>>from>>to;
if(My_graph.Have_edge(from,to))cout<<"该边存在!"<<endl;
else cout<<"该边不存在!"<<endl;
}
if(cmd==5){
cout<<"请输入需要查询度数的顶点:";
cin>>u;cout<<endl;
cout<<"顶点"<<u<<"的度数为:"<<My_graph.Get_degree(u)<<endl;
}
if(cmd==6){
cout<<"图的邻接矩阵为:"<<endl;
My_graph.prt_Gra();
}
if(cmd==7){
cout<<"请输入需要查询相邻点的顶点:";
cin>>u;cout<<endl;
cout<<"与顶点"<<u<<"相邻的点有:"<<endl;
My_graph.The_edge_node(u);
}
if(cmd==8){
My_graph.Clear_Vis();
cout<<"请输入起点:";
cin>>u;cout<<endl;
cout<<"深度优先遍历的结果为:"<<endl;
My_graph.DFS(u);cout<<endl;
}
if(cmd==9){
cout<<"请输入起点:";
cin>>u;cout<<endl;
cout<<"宽度优先遍历的结果为:"<<endl;
My_graph.BFS(u);cout<<endl;
}
}
return 0;
}
/*
6 9
0 1 10
0 3 20
0 5 3
1 2 3
1 3 5
3 4 11
2 4 15
3 5 10
4 5 3
*/
But when I run the code, CodeBlocks says ''multiple definition of My_graph'.
Then I choose to define Graph's object in main() instead of in Graph.h. But this time the exe will exit before execute main().
Process returned -1073741571 (0xC00000FD)
This is main()code
I want to figure out what happened in constructor.
Even if you are not allocating your data on the stack, you won't be able to execute your code. This is the amount of data you want to allocate:
const int maxn=1e3+10;
int is_vis[maxn];
int degree[maxn];
int Edges[maxn][maxn];
I don't think your computer has enough space.
Use vectors, and resize the edges matrix ont he fly (do you need a matrix anyway? Probably not)
std::vector<int> is_vis;
std::vector<int> degree;
std::vector<std::vector<int>> Edges; // Change this to something sensible, perhaps a list of connections?
This is only for one error message "multiple definition...". For the other error see #MatthieuBrucher answer.
class Graph{
....
} My_graph;
This declares an instance global object of type Graph called My_graph.
Once you have this instance you can not declare it again:
Graph My_graph; //ERROR
This re-declaration may come not only in some function ('main' is a function) , but also from including the same .h header several times without include-guards.

Trying C++ on Xcode on Mac- ERROR-exc_bad_access (code=1 address=0x100500000)

I have been trying to write a program where I have to read a binary file which has around 30 million long values and we have to find out the modes I have successfully done it using a smaller number of values but when I try with the file it always gives me the error- exc_bad_access (code=1 address=0x100500000), I am trying it in Xcode on my MAC and implementing in C++. The code is as below, can anyone help me out?
#include <iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
void mode(long data[], long size, long &num_modes, long modeNums[], long &maxFrequency);
int main()
{
long *data,*modeNums, size;
ifstream binaryin("TestData.bin", ios::binary);
binaryin.read(reinterpret_cast<char *>(&size), 4);
data = new(nothrow)long[size];
if(!data)
{ cout<<"Memory allocation error for data array, program will terminate\n";
system("pause");
exit(0); }
binaryin.read(reinterpret_cast<char *>(data),size*sizeof(long));
//cout<<"SIZE "<<size<<endl;
long num_modes;long maxFrequency;
modeNums=new(nothrow)long[size];
size=3000000;
mode(data,size,num_modes,modeNums,maxFrequency);
/* for(int i=0;i<20;i++)
cout<<"data[i]"<<data[i]<<endl;*/
// cout<<"maxFrequency= "<<maxFrequency;
// cout<<"\nnum_modes= "<<num_modes<<endl;
// for(int i=0;i<num_modes;i++)
// cout<<"modeNums[]= "<<modeNums[i]<<endl;
}
void mode(long data[], long size, long &num_modes, long modeNums[], long &maxFrequency)
{
// size=300000;
// cout<<"SIZE "<<size<<endl;
int cnt=0,val=0;// long *arr,*arr1;
vector<long> arr;
vector<long> arr1;
//arr=new(nothrow)long[size/2];
//arr1=new(nothrow)long[size/2];
// cout<<"INSIDE THE FUNCTION\n";
//cout<<"SIZE "<<size<<endl;
long k;
//cout<<"SIZE "<<size<<endl;
cout<<"\nstarting for loop\n";
for(int i=0;i<size;i++)
{ cout<<"Inside for loop\n";
cnt=0; k=(size-1);
long num=data[i];
int flag=0;
int temp=val;
while(temp!=0)
{ cout<<"inside while loop\n";
if(arr[temp]==num)
{ flag=1;}
temp--;
}
if(flag==0){
int count=0;
for(int j=0;j<(size/2);j++)
{// cout<<"Inside for which is inside while\n";
cout<<"data[j] "<<data[j]<<" "<<"data[k] "<<data[k]<<endl;
cout<<"COUNT "<<count++<<endl;
if(num==data[j] && num==data[k])
{ cnt+=2; }
else if(num==data[j]||num==data[k])
{ cnt++; }
k--;
}
arr.push_back(num);arr1.push_back(cnt);
val++;
}
else
flag=2;
}
cout<<"\nend of for loop\n";
// for(int i=0;i<val;i++)
// cout<<"NUM "<<arr[val]<<"Mode "<<arr1[val]<<endl;
maxFrequency=0;
for(int i=0;i<val;i++)
{
if(arr1[i]>maxFrequency)
maxFrequency=arr1[i];
}
num_modes=0; int value=0;
for(int i=0;i<val;i++)
{
if(arr1[i]==maxFrequency)
{ num_modes++;
modeNums[value]=arr[i];
value++; }
}
/* int value=0;
for(int i=0;i<val;i++)
{
if(maxFrequency==arr1[i])
{ modeNums[value]=arr[i];
value++;}
} */
// for(int i=0;i<val;i++)
// cout<<"Value "<<arr[i]<<" Mode "<<arr1[i]<<endl;
// cout<<"maxFrequency= "<<maxFrequency<<endl;
// cout<<"\nnum_modes= "<<num_modes<<endl;
cout<<"\nend of function\n";
}
enter image description here
This line:
size=3000000;
means that you allocate your arrays of a certain size (whatever you read from the file), then tell your mode function that those arrays are actually 3000000 longs in size. This could lead to a buffer overrun.
I can't see any reason for this line to be in there.
Also if you use new(nothrow) you should check the return value.

SPOJ: What is the difference between these two answers for KURUK14

I have solved this problem and got AC. My problem is related to equivalence of following two approaches. The first code got accepted, while the second didn't.
As far as I can discern, both are completely equivalent for all the (valid) test cases any human can think of. Am I wrong? If so, what test case can differentiate them?
Code#1 (Accepted one):
#include <cstdio>
bool* M;
bool proc(int N){
for(int j=0;j<=N;j++){
M[j]=false;
}
for(int i=0;i<N;i++){
int a=0;
scanf("%d",&a);
if(a>=N)
return false;
else if(!M[a])
M[a]=true;
else if(!M[N-1-a])
M[N-1-a]=true;
}
bool f = true;
for(int k=0;k<N;k++)
{
f = f && M[k];
}
return f;
}
int main() {
M=new bool[1002];
int num=0;
scanf("%d",&num);
while(num){
int N=0;
scanf("%d",&N);
if(proc(N))
printf("YES\n");
else
printf("NO\n");
num--;
}
return 0;
}
Code #2 (WA):
#include <cstdio>
bool* M;
bool proc(int N){
for(int j=0;j<=N;j++){
M[j]=false;
}
for(int i=0;i<N;i++){
int a=0;
scanf("%d",&a);
if(a>=N)
return false;
else if(!M[a])
M[a]=true;
else if(!M[N-1-a])
M[N-1-a]=true;
else
return false;
}
return true;
}
int main() {
//Exactly same as code#1
}
The bug has nothing to do with the algorithm itself—it's very possible both the algorithms are correct. But the second implementation is wrong.
When you reach a test case which should return NO, you exit the function prematurely. Which means there are some numbers from the current test case left unread in the input, which of course confuses further reading thoroughly. This means the bug only manifests when T > 1.